From d194828c4411453f2f84344fdfe3c1474bb05ff1 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sat, 15 Nov 2025 01:22:29 +0530 Subject: [PATCH 1/3] ISSUE-44: Hithomelabs/HomeLabDocker#44 Executing integration test every 6 hours --- .gitea/workflows/integration_test.yaml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.gitea/workflows/integration_test.yaml b/.gitea/workflows/integration_test.yaml index 3a4697c..688f37b 100644 --- a/.gitea/workflows/integration_test.yaml +++ b/.gitea/workflows/integration_test.yaml @@ -1,10 +1,8 @@ name: Daily cloudflare API integration test on: - push: - branches: [ test ] -# schedule: -# - cron: '0 * * * *' # Every hour -# workflow_dispatch: + schedule: + - cron: '0 */6 * * *' # Every hour + workflow_dispatch: jobs: cloudflare-api-test: -- 2.45.2 From 95ec64630a84950f5c7091880bcc00452e1de232 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sat, 15 Nov 2025 01:27:32 +0530 Subject: [PATCH 2/3] ISSUE-44: Hithomelabs/HomeLabDocker#44 making tests more verbose --- build.gradle | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/build.gradle b/build.gradle index c85d1f3..0800341 100644 --- a/build.gradle +++ b/build.gradle @@ -18,6 +18,11 @@ test { useJUnitPlatform { excludeTags 'integration' } + testLogging { + events "passed", "skipped", "failed", "standardOut", "standardError" + exceptionFormat "full" // shows full stack trace + showStandardStreams = true // shows println/log output + } } tasks.register('integrationTestOnly', Test) { @@ -26,6 +31,11 @@ tasks.register('integrationTestOnly', Test) { } description = 'Runs only integration tests tagged with @Tag("integration")' group = 'verification' + testLogging { + events "passed", "skipped", "failed" + exceptionFormat "full" + showStandardStreams = true + } } repositories { -- 2.45.2 From b30ae7cdbff9748487c242f7c7b0b4dcc3d0c180 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 16 Nov 2025 18:59:06 +0530 Subject: [PATCH 3/3] ISSUE-44: Hithomelabs/HomeLabDocker#44 adding more tests --- .../hithomelabs/CFTunnels/Models/Ingress.java | 41 +++------- .../CoudflareApiIntegrationTest.java | 78 +++++++++++++++---- 2 files changed, 74 insertions(+), 45 deletions(-) diff --git a/src/main/java/com/hithomelabs/CFTunnels/Models/Ingress.java b/src/main/java/com/hithomelabs/CFTunnels/Models/Ingress.java index 7c6c7be..005a02b 100644 --- a/src/main/java/com/hithomelabs/CFTunnels/Models/Ingress.java +++ b/src/main/java/com/hithomelabs/CFTunnels/Models/Ingress.java @@ -1,8 +1,17 @@ package com.hithomelabs.CFTunnels.Models; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + import java.util.List; import java.util.Map; +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter public class Ingress { private String service; @@ -10,40 +19,8 @@ public class Ingress { private Map originRequest; private String path; - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - public static boolean deleteByHostName(List ingressList, String toBeDeleted){ return ingressList.removeIf(ingress -> ingress.getHostname() != null && ingress.getHostname().equals(toBeDeleted)); } - public String getService() { - return service; - } - - public void setService(String service) { - this.service = service; - } - - public String getHostname() { - return hostname; - } - - public void setHostname(String hostname) { - this.hostname = hostname; - } - - public Map getOriginRequest() { - return originRequest; - } - - public void setOriginRequest(Map originRequest) { - this.originRequest = originRequest; - } } diff --git a/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java b/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java index 0ce0bc0..9553db1 100644 --- a/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java +++ b/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java @@ -1,25 +1,25 @@ package com.hithomelabs.CFTunnels.Integration; -import com.fasterxml.jackson.databind.ObjectMapper; import com.hithomelabs.CFTunnels.Config.CloudflareConfig; import com.hithomelabs.CFTunnels.Headers.AuthKeyEmailHeader; +import com.hithomelabs.CFTunnels.Models.Config; +import com.hithomelabs.CFTunnels.Models.Ingress; +import com.hithomelabs.CFTunnels.Models.TunnelResponse; +import com.hithomelabs.CFTunnels.Services.CloudflareAPIService; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.ActiveProfiles; +import org.springframework.web.client.RestTemplate; import java.util.List; import java.util.Map; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ActiveProfiles("integration") @@ -27,7 +27,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class CoudflareApiIntegrationTest { @Autowired - TestRestTemplate restTemplate; + RestTemplate restTemplate; @Autowired AuthKeyEmailHeader authKeyEmailHeader; @@ -35,21 +35,73 @@ public class CoudflareApiIntegrationTest { @Autowired CloudflareConfig cloudflareConfig; - private static ObjectMapper mapper = new ObjectMapper(); + @Autowired + CloudflareAPIService cloudflareAPIService; + + private static final String DEV_TUNNEL_ID = "50df9101-f625-4618-b7c5-100338a57124"; @Test @DisplayName("Calls cloudflare cfd tunnels API and checks that dev tunnel should be a part of the response") - public void getTunnelsTest(){ + public void testGetTunnelsTest() { + + ResponseEntity response = cloudflareAPIService.getCloudflareTunnels(); - // * * Resource URL to hit get request at - String url = "https://api.cloudflare.com/client/v4/accounts/" + cloudflareConfig.getAccountId() + "/cfd_tunnel"; - HttpEntity httpEntity = new HttpEntity<>("", authKeyEmailHeader.getHttpHeaders()); - ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, httpEntity, Map.class); assertEquals(HttpStatus.OK, response.getStatusCode()); + List> tunnelList = (List>) response.getBody().get("result"); boolean hasName = tunnelList.stream() .anyMatch(tunnel -> "devtunnel".equals(tunnel.get("name"))); + assertTrue(hasName); } + @Test + @DisplayName("Calls cloudflare API to get mappings for devtunnel tunnel") + public void testTunnelConfigurations() { + + ResponseEntity responseEntity = cloudflareAPIService.getCloudflareTunnelConfigurations(DEV_TUNNEL_ID, restTemplate, TunnelResponse.class); + + // * * Check if status code is 200 + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + + // * * Checking if mapping for devdocker exists + TunnelResponse tunnelResponse = responseEntity.getBody(); + boolean hasMatch = tunnelResponse.getResult().getConfig().getIngress().stream() + .anyMatch(ingress -> "devdocker.hithomelabs.com".equals(ingress.getHostname())); + assertTrue(hasMatch); + } + + @Test + @DisplayName("Inserts and deletes a mapping using Cloudflare API") + public void testAddAndDeleteMapping() { + + ResponseEntity beforeMapping = cloudflareAPIService.getCloudflareTunnelConfigurations(DEV_TUNNEL_ID, restTemplate, TunnelResponse.class); + + assertEquals(HttpStatus.OK, beforeMapping.getStatusCode()); + + Ingress ingress = new Ingress(); + ingress.setHostname("random.hithomelabs.com"); + ingress.setService("http://192.168.0.100:3457"); + + Config beforeInsertConfig = beforeMapping.getBody().getResult().getConfig(); + List beforeInsert = beforeInsertConfig.getIngress(); + beforeInsert.add(beforeInsert.size() - 1, ingress); + + ResponseEntity afterInsert = cloudflareAPIService.putCloudflareTunnelConfigurations(DEV_TUNNEL_ID, restTemplate, TunnelResponse.class, beforeInsertConfig); + + assertEquals(HttpStatus.OK, afterInsert.getStatusCode()); + Config afterInsertConfig = afterInsert.getBody().getResult().getConfig(); + List ingressList = afterInsertConfig.getIngress(); + + boolean hasIngress = ingressList.get(ingressList.size() - 2 ).getHostname().equals("random.hithomelabs.com"); + assertTrue(hasIngress); + + Boolean deleteSuccess = Ingress.deleteByHostName(ingressList, ingress.getHostname()); + assertTrue(deleteSuccess); + + ResponseEntity afterDelete = cloudflareAPIService.putCloudflareTunnelConfigurations(DEV_TUNNEL_ID, restTemplate, TunnelResponse.class, afterInsertConfig); + assertEquals(HttpStatus.OK, afterDelete.getStatusCode()); + assertFalse(afterDelete.getBody().getResult().getConfig().getIngress().stream().anyMatch(anyIngress -> "random.hithomelabs.com".equals(anyIngress.getHostname()))); + } + } -- 2.45.2