diff options
Diffstat (limited to 'controller-server/src/test/java/com/yahoo')
7 files changed, 37 insertions, 372 deletions
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandlerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandlerTest.java deleted file mode 100644 index f3147d2adde..00000000000 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandlerTest.java +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.hosted.controller.restapi.billing; - -import com.yahoo.config.provision.SystemName; -import com.yahoo.config.provision.TenantName; -import com.yahoo.vespa.hosted.controller.api.integration.billing.Bill; -import com.yahoo.vespa.hosted.controller.api.integration.billing.BillStatus; -import com.yahoo.vespa.hosted.controller.api.integration.billing.CollectionMethod; -import com.yahoo.vespa.hosted.controller.api.integration.billing.MockBillingController; -import com.yahoo.vespa.hosted.controller.api.integration.billing.PlanId; -import com.yahoo.vespa.hosted.controller.api.integration.billing.StatusHistory; -import com.yahoo.vespa.hosted.controller.api.role.Role; -import com.yahoo.vespa.hosted.controller.restapi.ContainerTester; -import com.yahoo.vespa.hosted.controller.restapi.ControllerContainerCloudTest; -import com.yahoo.vespa.hosted.controller.security.Auth0Credentials; -import com.yahoo.vespa.hosted.controller.security.CloudTenantSpec; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.io.File; -import java.math.BigDecimal; -import java.time.LocalDate; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.TreeMap; - -import static com.yahoo.application.container.handler.Request.Method.GET; -import static com.yahoo.application.container.handler.Request.Method.PATCH; -import static com.yahoo.application.container.handler.Request.Method.POST; -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * @author olaa - */ -public class BillingApiHandlerTest extends ControllerContainerCloudTest { - - private static final String responseFiles = "src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/responses/"; - private static final TenantName tenant = TenantName.from("tenant1"); - private static final TenantName tenant2 = TenantName.from("tenant2"); - private static final Set<Role> tenantRole = Set.of(Role.administrator(tenant)); - private static final Set<Role> financeAdmin = Set.of(Role.hostedAccountant()); - private MockBillingController billingController; - - private ContainerTester tester; - - @BeforeEach - public void setup() { - tester = new ContainerTester(container, responseFiles); - billingController = (MockBillingController) tester.serviceRegistry().billingController(); - } - - @Override - protected SystemName system() { - return SystemName.PublicCd; - } - - @Override - protected String variablePartXml() { - return " <component id='com.yahoo.vespa.hosted.controller.security.CloudAccessControlRequests'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.security.CloudAccessControl'/>\n" + - - " <handler id='com.yahoo.vespa.hosted.controller.restapi.billing.BillingApiHandler'>\n" + - " <binding>http://*/billing/v1/*</binding>\n" + - " </handler>\n" + - - " <http>\n" + - " <server id='default' port='8080' />\n" + - " <filtering>\n" + - " <request-chain id='default'>\n" + - " <filter id='com.yahoo.vespa.hosted.controller.restapi.filter.ControllerAuthorizationFilter'/>\n" + - " <binding>http://*/*</binding>\n" + - " </request-chain>\n" + - " </filtering>\n" + - " </http>\n"; - } - - @Test - void list_plans() { - var listPlansRequest = request("/billing/v1/plans", GET) - .roles(Role.hostedAccountant()); - tester.assertResponse(listPlansRequest, "{\"plans\":[{\"id\":\"trial\",\"name\":\"Free Trial - for testing purposes\"},{\"id\":\"paid\",\"name\":\"Paid Plan - for testing purposes\"},{\"id\":\"none\",\"name\":\"None Plan - for testing purposes\"}]}"); - } - - @Test - void response_list_bills() { - var bill = createBill(); - - billingController.addBill(tenant, bill, true); - billingController.addBill(tenant, bill, false); - billingController.setPlan(tenant, PlanId.from("some-plan"), true, false); - - var request = request("/billing/v1/tenant/tenant1/billing?until=2020-05-28").roles(tenantRole); - tester.assertResponse(request, new File("tenant-billing-view.json")); - - } - - @Test - void test_bill_creation() { - var bills = billingController.getBillsForTenant(tenant); - assertEquals(0, bills.size()); - - String requestBody = "{\"tenant\":\"tenant1\", \"startTime\":\"2020-04-20\", \"endTime\":\"2020-05-20\"}"; - var request = request("/billing/v1/invoice", POST) - .data(requestBody) - .roles(tenantRole); - - tester.assertResponse(request, accessDenied, 403); - request.roles(financeAdmin); - tester.assertResponse(request, new File("invoice-creation-response.json")); - - bills = billingController.getBillsForTenant(tenant); - assertEquals(1, bills.size()); - Bill bill = bills.get(0); - assertEquals("2020-04-20T00:00Z", bill.getStartTime().toString()); - assertEquals("2020-05-21T00:00Z", bill.getEndTime().toString()); - - assertEquals("2020-04-20", bill.getStartDate().toString()); - assertEquals("2020-05-20", bill.getEndDate().toString()); - } - - @Test - void adding_and_listing_line_item() { - - var requestBody = "{" + - "\"description\":\"some description\"," + - "\"amount\":\"123.45\" " + - "}"; - - var request = request("/billing/v1/invoice/tenant/tenant1/line-item", POST) - .data(requestBody) - .roles(financeAdmin); - - tester.assertResponse(request, "{\"message\":\"Added line item for tenant tenant1\"}"); - - var lineItems = billingController.getUnusedLineItems(tenant); - assertEquals(1, lineItems.size()); - Bill.LineItem lineItem = lineItems.get(0); - assertEquals("some description", lineItem.description()); - assertEquals(new BigDecimal("123.45"), lineItem.amount()); - - request = request("/billing/v1/invoice/tenant/tenant1/line-item") - .roles(financeAdmin); - - tester.assertResponse(request, new File("line-item-list.json")); - } - - @Test - void adding_new_status() { - billingController.addBill(tenant, createBill(), true); - - var requestBody = "{\"status\":\"CLOSED\"}"; - var request = request("/billing/v1/invoice/id-1/status", POST) - .data(requestBody) - .roles(financeAdmin); - tester.assertResponse(request, "{\"message\":\"Updated status of invoice id-1\"}"); - - var bill = billingController.getBillsForTenant(tenant).get(0); - assertEquals(BillStatus.CLOSED, bill.status()); - } - - @Test - void list_all_unbilled_items() { - tester.controller().tenants().create(new CloudTenantSpec(tenant, ""), new Auth0Credentials(() -> "foo", Set.of(Role.hostedOperator()))); - tester.controller().tenants().create(new CloudTenantSpec(tenant2, ""), new Auth0Credentials(() -> "foo", Set.of(Role.hostedOperator()))); - - var bill = createBill(); - billingController.setPlan(tenant, PlanId.from("some-plan"), true, false); - billingController.setPlan(tenant2, PlanId.from("some-plan"), true, false); - billingController.addBill(tenant, bill, false); - billingController.addLineItem(tenant, "support", new BigDecimal("42"), Optional.empty(), "Smith"); - billingController.addBill(tenant2, bill, false); - - var request = request("/billing/v1/billing?until=2020-05-28").roles(financeAdmin); - - tester.assertResponse(request, new File("billing-all-tenants.json")); - } - - @Test - void csv_export() { - var bill = createBill(); - billingController.addBill(tenant, bill, true); - var csvRequest = request("/billing/v1/invoice/export", GET).roles(financeAdmin); - tester.assertResponse(csvRequest.get(), new File("billing-all-invoices"), 200, false); - } - - @Test - void patch_collection_method() { - test_patch_collection_with_field_name("collectionMethod"); - test_patch_collection_with_field_name("collection"); - } - - private void test_patch_collection_with_field_name(String fieldName) { - var planRequest = request("/billing/v1/tenant/tenant1/collection", PATCH) - .data("{\"" + fieldName + "\": \"invoice\"}") - .roles(financeAdmin); - tester.assertResponse(planRequest, "Collection method updated to INVOICE"); - assertEquals(CollectionMethod.INVOICE, billingController.getCollectionMethod(tenant)); - - // Test that not event tenant administrators can do this - planRequest = request("/billing/v1/tenant/tenant1/collection", PATCH) - .data("{\"collectionMethod\": \"epay\"}") - .roles(tenantRole); - tester.assertResponse(planRequest, accessDenied, 403); - assertEquals(CollectionMethod.INVOICE, billingController.getCollectionMethod(tenant)); - } - - static Bill createBill() { - var start = LocalDate.of(2020, 5, 23).atStartOfDay(ZoneOffset.UTC); - var end = start.toLocalDate().plusDays(6).atStartOfDay(ZoneOffset.UTC); - var statusHistory = new StatusHistory(new TreeMap<>(Map.of(start, BillStatus.OPEN))); - return new Bill( - Bill.Id.of("id-1"), - TenantName.defaultName(), - statusHistory, - List.of(createLineItem(start)), - start, - end - ); - } - - static Bill.LineItem createLineItem(ZonedDateTime addedAt) { - return new Bill.LineItem( - "some-id", - "description", - new BigDecimal("123.00"), - "paid", - "Smith", - addedAt - ); - } - -} diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandlerV2Test.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandlerV2Test.java index 4d3297ddb0c..46c1aa107f0 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandlerV2Test.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/BillingApiHandlerV2Test.java @@ -4,7 +4,10 @@ package com.yahoo.vespa.hosted.controller.restapi.billing; import com.yahoo.application.container.handler.Request; import com.yahoo.config.provision.TenantName; import com.yahoo.test.ManualClock; +import com.yahoo.vespa.hosted.controller.api.integration.billing.Bill; +import com.yahoo.vespa.hosted.controller.api.integration.billing.BillStatus; import com.yahoo.vespa.hosted.controller.api.integration.billing.MockBillingController; +import com.yahoo.vespa.hosted.controller.api.integration.billing.StatusHistory; import com.yahoo.vespa.hosted.controller.api.role.Role; import com.yahoo.vespa.hosted.controller.restapi.ContainerTester; import com.yahoo.vespa.hosted.controller.restapi.ControllerContainerCloudTest; @@ -13,8 +16,15 @@ import com.yahoo.vespa.hosted.controller.security.CloudTenantSpec; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.math.BigDecimal; import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.TreeMap; /** * @author ogronnesby @@ -29,11 +39,6 @@ public class BillingApiHandlerV2Test extends ControllerContainerCloudTest { private static final Set<Role> tenantAdmin = Set.of(Role.administrator(tenant)); private static final Set<Role> financeAdmin = Set.of(Role.hostedAccountant()); - private static final String ACCESS_DENIED = "{\n" + - " \"code\" : 403,\n" + - " \"message\" : \"Access denied\"\n" + - "}"; - private MockBillingController billingController; private ContainerTester tester; @@ -44,7 +49,7 @@ public class BillingApiHandlerV2Test extends ControllerContainerCloudTest { var clock = (ManualClock) tester.controller().serviceRegistry().clock(); clock.setInstant(Instant.parse("2021-04-13T00:00:00Z")); billingController = (MockBillingController) tester.serviceRegistry().billingController(); - billingController.addBill(tenant, BillingApiHandlerTest.createBill(), true); + billingController.addBill(tenant, createBill(), true); } @Override @@ -122,7 +127,7 @@ public class BillingApiHandlerV2Test extends ControllerContainerCloudTest { @Test void require_accountant_preview() { var accountantRequest = request("/billing/v2/accountant/preview").roles(Role.hostedAccountant()); - billingController.uncommittedBills.put(tenant, BillingApiHandlerTest.createBill()); + billingController.uncommittedBills.put(tenant, createBill()); tester.assertResponse(accountantRequest, """ {"tenants":[{"tenant":"tenant1","plan":{"id":"trial","name":"Free Trial - for testing purposes"},"quota":{"budget":-1.0},"collection":"AUTO","lastBill":"2020-05-23","unbilled":"123.00"}]}"""); @@ -245,4 +250,29 @@ public class BillingApiHandlerV2Test extends ControllerContainerCloudTest { tester.assertResponse(accountantRequest, """ {"tenant":"tenant1","plan":{"id":"trial","name":"Free Trial - for testing purposes","billed":false,"supported":false},"billing":{},"collection":"AUTO"}"""); } + + private static Bill createBill() { + var start = LocalDate.of(2020, 5, 23).atStartOfDay(ZoneOffset.UTC); + var end = start.toLocalDate().plusDays(6).atStartOfDay(ZoneOffset.UTC); + var statusHistory = new StatusHistory(new TreeMap<>(Map.of(start, BillStatus.OPEN))); + return new Bill( + Bill.Id.of("id-1"), + TenantName.defaultName(), + statusHistory, + List.of(createLineItem(start)), + start, + end + ); + } + + static Bill.LineItem createLineItem(ZonedDateTime addedAt) { + return new Bill.LineItem( + "some-id", + "description", + new BigDecimal("123.00"), + "paid", + "Smith", + addedAt + ); + } } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/responses/billing-all-invoices b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/responses/billing-all-invoices deleted file mode 100644 index 957ed858951..00000000000 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/responses/billing-all-invoices +++ /dev/null @@ -1,2 +0,0 @@ -ID,Tenant,From,To,CpuHours,MemoryHours,DiskHours,Cpu,Memory,Disk,Additional -id-1,default,2020-05-23,2020-05-28,0.00,0.00,0.00,0.00,0.00,0.00,123.00 diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/responses/billing-all-tenants.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/responses/billing-all-tenants.json deleted file mode 100644 index 85c34edf7db..00000000000 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/responses/billing-all-tenants.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "until": "2020-05-28", - "tenants": [ - { - "tenant": "tenant1", - "plan": "some-plan", - "planName": "Plan with id: some-plan", - "collection": "AUTO", - "current": { - "amount": "123.00", - "status": "accrued", - "from": "2020-05-23", - "items": [ - { - "id": "some-id", - "description": "description", - "amount": "123.00", - "plan": "paid", - "planName": "Plan with id: paid", - "majorVersion": 0 - } - ] - }, - "additional": { - "items": [ - { - "id": "line-item-id", - "description": "support", - "amount": "42.00", - "plan": "paid", - "planName": "Plan with id: paid", - "majorVersion": 0 - } - ] - } - }, - { - "tenant": "tenant2", - "plan": "some-plan", - "planName": "Plan with id: some-plan", - "collection": "AUTO", - "current": { - "amount": "123.00", - "status": "accrued", - "from": "2020-05-23", - "items": [ - { - "id": "some-id", - "description": "description", - "amount": "123.00", - "plan": "paid", - "planName": "Plan with id: paid", - "majorVersion": 0 - } - ] - }, - "additional": { - "items": [ ] - } - } - ] -} diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/responses/invoice-creation-response.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/responses/invoice-creation-response.json deleted file mode 100644 index 49fde010c58..00000000000 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/responses/invoice-creation-response.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "message": "Created invoice with ID id-123", - "id": "id-123" -} diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/responses/line-item-list.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/responses/line-item-list.json deleted file mode 100644 index 8b69ea78754..00000000000 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/responses/line-item-list.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "lineItems": [ - { - "id": "line-item-id", - "description": "some description", - "amount": "123.45", - "plan": "paid", - "planName": "Plan with id: paid", - "majorVersion": 0 - } - ] -} diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/responses/tenant-billing-view.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/responses/tenant-billing-view.json deleted file mode 100644 index 4e255205e19..00000000000 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/billing/responses/tenant-billing-view.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "until": "2020-05-28", - "plan": "some-plan", - "planName": "Plan with id: some-plan", - "current": { - "amount": "123.00", - "status": "accrued", - "from": "2020-05-23", - "items": [ - { - "id": "some-id", - "description": "description", - "amount": "123.00", - "plan": "paid", - "planName": "Plan with id: paid", - "majorVersion": 0 - } - ] - }, - "additional": { - "items": [ ] - }, - "bills": [ - { - "id": "id-1", - "from": "2020-05-23", - "to": "2020-05-28", - "amount": "123.00", - "status": "OPEN", - "statusHistory": [ - { - "at": "2020-05-23", - "status": "OPEN" - } - ], - "items": [ - { - "id": "some-id", - "description": "description", - "amount": "123.00", - "plan": "paid", - "planName": "Plan with id: paid", - "majorVersion": 0 - } - ] - } - ], - "collection": "AUTO" -} |