Skip to content

Commit ea0674d

Browse files
committed
test(seaweedfs): add Prometheus metrics usage and fallback tests
Adds testGetAllBucketsUsageFromMetrics verifying the metrics path returns per-bucket sizes from a single scrape, filters unmanaged buckets, and does not call ListObjectsV2. Adds testGetAllBucketsUsageMetricsFailureFallsBackToList verifying that an HTTP 503 from the metrics endpoint falls back to the ListObjectsV2 scan.
1 parent 0349369 commit ea0674d

1 file changed

Lines changed: 66 additions & 0 deletions

File tree

plugins/storage/object/seaweedfs/src/test/java/org/apache/cloudstack/storage/datastore/driver/SeaweedFSObjectStoreDriverImplTest.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,4 +767,70 @@ public void testGetAllBucketsUsage() throws Exception {
767767
assertEquals(300L, usage.get("b1").longValue());
768768
assertEquals(500L, usage.get("b2").longValue());
769769
}
770+
771+
@Test
772+
public void testGetAllBucketsUsageFromMetrics() throws Exception {
773+
doReturn("http://metrics.local:9327").when(driver).getMetricsUrl(TEST_STORE_ID);
774+
775+
List<BucketVO> buckets = new ArrayList<>();
776+
buckets.add(new BucketVO(TEST_ACCOUNT_ID, TEST_DOMAIN_ID, TEST_STORE_ID, "b1", null, false, false, false, null));
777+
buckets.add(new BucketVO(TEST_ACCOUNT_ID, TEST_DOMAIN_ID, TEST_STORE_ID, "b2", null, false, false, false, null));
778+
when(bucketDao.listByObjectStoreId(TEST_STORE_ID)).thenReturn(buckets);
779+
780+
// Mock the HTTP client to return a Prometheus text exposition response
781+
String metricsBody = "# HELP seaweed_s3_bucket_size_bytes Current size\n" +
782+
"seaweed_s3_bucket_size_bytes{bucket=\"b1\"} 12345678\n" +
783+
"seaweed_s3_bucket_size_bytes{bucket=\"b2\"} 87654321\n" +
784+
"seaweed_s3_bucket_size_bytes{bucket=\"other\"} 999\n";
785+
HttpClient mockHttpClient = mock(HttpClient.class);
786+
HttpResponse<String> mockResponse = mock(HttpResponse.class);
787+
when(mockResponse.statusCode()).thenReturn(200);
788+
when(mockResponse.body()).thenReturn(metricsBody);
789+
when(mockHttpClient.send(ArgumentMatchers.<HttpRequest>any(),
790+
ArgumentMatchers.<HttpResponse.BodyHandler<String>>any()))
791+
.thenReturn(mockResponse);
792+
doReturn(mockHttpClient).when(driver).getS3ExtensionHttpClient();
793+
794+
Map<String, Long> usage = driver.getAllBucketsUsage(TEST_STORE_ID);
795+
assertNotNull(usage);
796+
assertEquals(2, usage.size());
797+
assertEquals(12345678L, usage.get("b1").longValue());
798+
assertEquals(87654321L, usage.get("b2").longValue());
799+
// "other" bucket is not managed by CloudStack and must be filtered out
800+
assertFalse(usage.containsKey("other"));
801+
// S3 ListObjectsV2 must not be called when metricsUrl is configured
802+
verify(s3Client, never()).listObjectsV2(any(ListObjectsV2Request.class));
803+
}
804+
805+
@Test
806+
public void testGetAllBucketsUsageMetricsFailureFallsBackToList() throws Exception {
807+
doReturn("http://metrics.local:9327").when(driver).getMetricsUrl(TEST_STORE_ID);
808+
doReturn(s3Client).when(driver).getS3ClientByStoreId(TEST_STORE_ID);
809+
810+
List<BucketVO> buckets = new ArrayList<>();
811+
buckets.add(new BucketVO(TEST_ACCOUNT_ID, TEST_DOMAIN_ID, TEST_STORE_ID, "b1", null, false, false, false, null));
812+
when(bucketDao.listByObjectStoreId(TEST_STORE_ID)).thenReturn(buckets);
813+
814+
// Metrics scrape returns HTTP 503 -> fallback to ListObjectsV2
815+
HttpClient mockHttpClient = mock(HttpClient.class);
816+
HttpResponse<String> mockResponse = mock(HttpResponse.class);
817+
when(mockResponse.statusCode()).thenReturn(503);
818+
when(mockResponse.body()).thenReturn("Service Unavailable");
819+
when(mockHttpClient.send(ArgumentMatchers.<HttpRequest>any(),
820+
ArgumentMatchers.<HttpResponse.BodyHandler<String>>any()))
821+
.thenReturn(mockResponse);
822+
doReturn(mockHttpClient).when(driver).getS3ExtensionHttpClient();
823+
824+
ListObjectsV2Result b1Result = mock(ListObjectsV2Result.class);
825+
S3ObjectSummary s1 = new S3ObjectSummary(); s1.setSize(42L);
826+
List<S3ObjectSummary> summaries = new ArrayList<>(); summaries.add(s1);
827+
when(b1Result.getObjectSummaries()).thenReturn(summaries);
828+
when(b1Result.isTruncated()).thenReturn(false);
829+
when(s3Client.listObjectsV2(any(ListObjectsV2Request.class))).thenReturn(b1Result);
830+
831+
Map<String, Long> usage = driver.getAllBucketsUsage(TEST_STORE_ID);
832+
assertNotNull(usage);
833+
assertEquals(1, usage.size());
834+
assertEquals(42L, usage.get("b1").longValue());
835+
}
770836
}

0 commit comments

Comments
 (0)