diff --git a/packages/grid_client/tests/modules/applications/gitea.test.ts b/packages/grid_client/tests/modules/applications/gitea.test.ts new file mode 100644 index 0000000000..3c3ffe7ab4 --- /dev/null +++ b/packages/grid_client/tests/modules/applications/gitea.test.ts @@ -0,0 +1,203 @@ +import axios from "axios"; +import { setTimeout } from "timers/promises"; + +import { + Features, + FilterOptions, + GatewayNameModel, + generateString, + GridClient, + MachinesModel, + randomChoice, +} from "../../../src"; +import { config, getClient } from "../../client_loader"; +import { generateInt, getOnlineNode, log } from "../../utils"; + +jest.setTimeout(1250000); + +let gridClient: GridClient; +let deploymentName: string; + +beforeAll(async () => { + gridClient = await getClient(); + deploymentName = "gt" + generateString(10); + gridClient.clientOptions.projectName = `gitea/${deploymentName}`; + gridClient._connect(); + return gridClient; +}); + +test("TC2954 - Applications: Deploy Gitea", async () => { + /********************************************** + Test Suite: Grid3_Client_TS (Automated) + Test Cases: TC2954 - Applications: Deploy Gitea + Scenario: + - Generate Test Data/Gitea Config/Gateway Config. + - Select a Node To Deploy the Gitea on. + - Select a Gateway Node To Deploy the gateway on. + - Deploy the Gitea solution. + - Assert that the generated data matches + the deployment details. + - Pass the IP of the Created Gitea to the Gateway + Config. + - Deploy the Gateway. + - Assert that the generated data matches + the deployment details. + - Assert that the Gateway points at the IP + of the created Gitea. + - Assert that the returned domain is working + and returns correct data. + **********************************************/ + const name = "gw" + generateString(10).toLowerCase(); + const tlsPassthrough = false; + const cpu = 1; + const memory = 2; + const rootfsSize = 2; + const diskSize = 15; + const networkName = generateString(15); + const vmName = generateString(15); + const diskName = generateString(15); + const mountPoint = "/var/lib/docker"; + const publicIp = false; + const ipRangeClassA = "10." + generateInt(1, 255) + ".0.0/16"; + const ipRangeClassB = "172." + generateInt(16, 31) + ".0.0/16"; + const ipRangeClassC = "192.168.0.0/16"; + const ipRange = randomChoice([ipRangeClassA, ipRangeClassB, ipRangeClassC]); + const metadata = "{'deploymentType': 'gitea'}"; + const description = "test deploying Gitea via ts grid3 client"; + + // Gateway Node Selection + const gatewayNodes = await gridClient.capacity.filterNodes({ + features: [Features.wireguard, Features.mycelium], + gateway: true, + farmId: 1, + availableFor: await gridClient.twins.get_my_twin_id(), + } as FilterOptions); + if (gatewayNodes.length === 0) throw new Error("No nodes available to complete this test"); + const GatewayNode = gatewayNodes[generateInt(0, gatewayNodes.length - 1)]; + + // Node Selection + const nodes = await gridClient.capacity.filterNodes({ + features: [Features.wireguard, Features.mycelium], + cru: cpu, + mru: memory, + sru: rootfsSize + diskSize, + farmId: 1, + availableFor: await gridClient.twins.get_my_twin_id(), + } as FilterOptions); + const nodeId = await getOnlineNode(nodes); + if (nodeId === -1) throw new Error("No nodes available to complete this test"); + const domain = name + "." + GatewayNode.publicConfig.domain; + + // VM Model + const vms: MachinesModel = { + name: deploymentName, + network: { + name: networkName, + ip_range: ipRange, + }, + machines: [ + { + name: vmName, + node_id: nodeId, + cpu: cpu, + memory: 1024 * memory, + rootfs_size: rootfsSize, + disks: [ + { + name: diskName, + size: diskSize, + mountpoint: mountPoint, + }, + ], + flist: "https://hub.grid.tf/petep.3bot/threefolddev-gitea-latest.flist", + entrypoint: "/sbin/zinit init", + public_ip: publicIp, + planetary: true, + mycelium: true, + env: { + SSH_KEY: config.ssh_key, + GITEA__HOSTNAME: domain, + GITEA__ROOT_EMAIL: "admin@gitea.com", + GITEA__ROOT_PASSWORD: "adminpassword", + }, + }, + ], + metadata: metadata, + description: description, + }; + + const res = await gridClient.machines.deploy(vms); + log(res); + + // Contracts Assertions + expect(res.contracts.created).toHaveLength(1); + expect(res.contracts.updated).toHaveLength(0); + expect(res.contracts.deleted).toHaveLength(0); + + const result = await gridClient.machines.getObj(vms.name); + log(result); + + // Gateway Backend Configuration + const backends = ["http://[" + result[0].planetary + "]:3000"]; + log(backends); + + // Gateway Model + const gw: GatewayNameModel = { + name: name, + node_id: GatewayNode.nodeId, + tls_passthrough: tlsPassthrough, + backends: backends, + }; + + const gatewayRes = await gridClient.gateway.deploy_name(gw); + log(gatewayRes); + + // Gateway Assertions + expect(gatewayRes.contracts.created).toHaveLength(1); + + const gatewayResult = await gridClient.gateway.getObj(gw.name); + log(gatewayResult); + + // Gateway Assertions + expect(gatewayResult[0].name).toBe(name); + expect(gatewayResult[0].backends).toStrictEqual(backends); + + const site = "https://" + gatewayResult[0].domain; + let reachable = false; + + for (let i = 0; i <= 250; i++) { + const wait = await setTimeout(5000, "Waiting for gateway to be ready"); + log(wait); + + await axios + .get(site) + .then(res => { + log("Gateway is reachable"); + log(res.status); + log(res.statusText); + expect(res.status).toBe(200); + reachable = true; + }) + .catch(() => { + log("Gateway is not reachable"); + }); + if (reachable) break; + if (i === 250) throw new Error("Gateway is unreachable after retries"); + } +}); + +afterAll(async () => { + const vmNames = await gridClient.machines.list(); + for (const name of vmNames) { + const res = await gridClient.machines.delete({ name }); + log(res); + } + + const gwNames = await gridClient.gateway.list(); + for (const name of gwNames) { + const res = await gridClient.gateway.delete_name({ name }); + log(res); + } + + return await gridClient.disconnect(); +}, 130000); diff --git a/packages/grid_client/tests/modules/applications/jenkins.test.ts b/packages/grid_client/tests/modules/applications/jenkins.test.ts new file mode 100644 index 0000000000..6a5e9af106 --- /dev/null +++ b/packages/grid_client/tests/modules/applications/jenkins.test.ts @@ -0,0 +1,206 @@ +import axios from "axios"; +import { setTimeout } from "timers/promises"; + +import { + Features, + FilterOptions, + GatewayNameModel, + generateString, + GridClient, + MachinesModel, + randomChoice, +} from "../../../src"; +import { config, getClient } from "../../client_loader"; +import { generateInt, getOnlineNode, log } from "../../utils"; + +jest.setTimeout(1250000); + +let gridClient: GridClient; +let deploymentName: string; + +beforeAll(async () => { + gridClient = await getClient(); + deploymentName = "jk" + generateString(10); + gridClient.clientOptions.projectName = `jenkins/${deploymentName}`; + gridClient._connect(); + return gridClient; +}); + +test("TC2953 - Applications: Deploy Jenkins", async () => { + /********************************************** + Test Suite: Grid3_Client_TS (Automated) + Test Cases: TC2953 - Applications: Deploy jenkins + Scenario: + - Generate Test Data/jenkins Config/Gateway Config. + - Select a Node To Deploy the jenkins on. + - Select a Gateway Node To Deploy the gateway on. + - Deploy the jenkins solution. + - Assert that the generated data matches + the deployment details. + - Pass the IP of the Created jenkins to the Gateway + Config. + - Deploy the Gateway. + - Assert that the generated data matches + the deployment details. + - Assert that the Gateway points at the IP + of the created jenkins. + - Assert that the returned domain is working + and returns correct data. + **********************************************/ + // Test Data + const name = "gw" + generateString(10).toLowerCase(); + const tlsPassthrough = false; + const cpu = 4; + const memory = 8; + const rootfsSize = 10; + const diskSize = 100; + const networkName = generateString(15); + const vmName = generateString(15); + const diskName = generateString(15); + const mountPoint = "/mnt/data"; + const publicIp = false; + const ipRangeClassA = "10." + generateInt(1, 255) + ".0.0/16"; + const ipRangeClassB = "172." + generateInt(16, 31) + ".0.0/16"; + const ipRangeClassC = "192.168.0.0/16"; + const ipRange = randomChoice([ipRangeClassA, ipRangeClassB, ipRangeClassC]); + const metadata = "{'deploymentType': 'jenkins'}"; + const description = "Test deploying Jenkins via ts grid3 client"; + + // GatewayNode Selection + const gatewayNodes = await gridClient.capacity.filterNodes({ + features: [Features.wireguard, Features.mycelium], + gateway: true, + farmId: 1, + availableFor: await gridClient.twins.get_my_twin_id(), + } as FilterOptions); + if (gatewayNodes.length == 0) throw new Error("No nodes available to complete this test"); + const GatewayNode = gatewayNodes[generateInt(0, gatewayNodes.length - 1)]; + + // Node Selection + const nodes = await gridClient.capacity.filterNodes({ + features: [Features.wireguard, Features.mycelium], + cru: cpu, + mru: memory, + sru: rootfsSize + diskSize, + farmId: 1, + availableFor: await gridClient.twins.get_my_twin_id(), + } as FilterOptions); + const nodeId = await getOnlineNode(nodes); + if (nodeId == -1) throw new Error("No nodes available to complete this test"); + const domain = name + "." + GatewayNode.publicConfig.domain; + + // VM Model + const vms: MachinesModel = { + name: deploymentName, + network: { + name: networkName, + ip_range: ipRange, + }, + machines: [ + { + name: vmName, + node_id: nodeId, + cpu: cpu, + memory: 1024 * memory, + rootfs_size: rootfsSize, + disks: [ + { + name: diskName, + size: diskSize, + mountpoint: mountPoint, + }, + ], + flist: "https://hub.grid.tf/tf-official-apps/jenkins-latest.flist", + entrypoint: "/sbin/zinit init", + public_ip: publicIp, + planetary: true, + mycelium: true, + env: { + SSH_KEY: config.ssh_key, + JENKINS_HOSTNAME: domain, + JENKINS_ADMIN_USERNAME: "admin", + JENKINS_ADMIN_PASSWORD: "adminpassword", + }, + }, + ], + metadata: metadata, + description: description, + }; + + const res = await gridClient.machines.deploy(vms); + log(res); + + // Contracts Assertions + expect(res.contracts.created).toHaveLength(1); + expect(res.contracts.updated).toHaveLength(0); + expect(res.contracts.deleted).toHaveLength(0); + + const result = await gridClient.machines.getObj(vms.name); + log(result); + + // Gateway Backend Configuration + const backends = ["http://[" + result[0].planetary + "]:80"]; + log(backends); + + // Gateway Model + const gw: GatewayNameModel = { + name: name, + node_id: GatewayNode.nodeId, + tls_passthrough: tlsPassthrough, + backends: backends, + }; + + const gatewayRes = await gridClient.gateway.deploy_name(gw); + log(gatewayRes); + + // Gateway Assertions + expect(gatewayRes.contracts.created).toHaveLength(1); + + const gatewayResult = await gridClient.gateway.getObj(gw.name); + log(gatewayResult); + + // Gateway Assertions + expect(gatewayResult[0].name).toBe(name); + expect(gatewayResult[0].backends).toStrictEqual(backends); + + // Gateway reachability check + const site = "http://" + gatewayResult[0].domain + "/login?from=%2F"; + log(`Testing Gateway URL: ${site}`); + let reachable = false; + + for (let i = 0; i <= 250; i++) { + const wait = await setTimeout(5000, "Waiting for gateway to be ready"); + log(wait); + + await axios + .get(site) + .then(res => { + log("Gateway is reachable"); + log(res.status); + log(res.statusText); + expect(res.status).toBe(200); + reachable = true; + }) + .catch(() => { + log("Gateway is not reachable"); + }); + if (reachable) break; + if (i === 250) throw new Error("Gateway is unreachable after retries"); + } +}); + +afterAll(async () => { + const vmNames = await gridClient.machines.list(); + for (const name of vmNames) { + const res = await gridClient.machines.delete({ name }); + log(res); + } + + const gwNames = await gridClient.gateway.list(); + for (const name of gwNames) { + const res = await gridClient.gateway.delete_name({ name }); + log(res); + } + + return await gridClient.disconnect(); +}, 130000); diff --git a/packages/grid_client/tests/modules/applications/jitsi.test.ts b/packages/grid_client/tests/modules/applications/jitsi.test.ts new file mode 100644 index 0000000000..63e936994b --- /dev/null +++ b/packages/grid_client/tests/modules/applications/jitsi.test.ts @@ -0,0 +1,202 @@ +import axios from "axios"; +import { setTimeout } from "timers/promises"; + +import { + Features, + FilterOptions, + GatewayNameModel, + generateString, + GridClient, + MachinesModel, + randomChoice, +} from "../../../src"; +import { config, getClient } from "../../client_loader"; +import { generateInt, getOnlineNode, log } from "../../utils"; + +jest.setTimeout(1250000); + +let gridClient: GridClient; +let deploymentName: string; + +beforeAll(async () => { + gridClient = await getClient(); + deploymentName = "jitsi" + generateString(10); + gridClient.clientOptions.projectName = `jitsi/${deploymentName}`; + gridClient._connect(); + return gridClient; +}); + +test("TCXXXX - Applications: Deploy Jitsi", async () => { + /********************************************** + Test Suite: Grid3_Client_TS (Automated) + Test Cases: TCXXXX - Applications: Deploy Jitsi + Scenario: + - Generate Test Data/Jitsi Config/Gateway Config. + - Select a Node To Deploy the Jitsi on. + - Select a Gateway Node To Deploy the gateway on. + - Deploy the Jitsi solution. + - Assert that the generated data matches + the deployment details. + - Pass the IP of the Created Jitsi instance + to the Gateway Config. + - Deploy the Gateway. + - Assert that the generated data matches + the deployment details. + - Assert that the Gateway points at the IP + of the created Jitsi. + - Assert that the returned domain is working + and returns correct data. + **********************************************/ + + // Test Data + const name = "gw" + generateString(10).toLowerCase(); + const tlsPassthrough = false; + const cpu = 2; + const memory = 4; + const rootfsSize = 0; + const diskSize = 50; + const networkName = generateString(15); + const vmName = generateString(15); + const diskName = generateString(15); + const mountPoint = "/mnt/data"; + const publicIp = false; + const ipRange = "10.251.0.0/16"; + const metadata = "{'deploymentType': 'jitsi'}"; + const description = "Test deploying Jitsi via ts grid3 client"; + + // Gateway Node Selection + const gatewayNodes = await gridClient.capacity.filterNodes({ + features: [Features.wireguard, Features.mycelium], + gateway: true, + farmId: 1, + availableFor: await gridClient.twins.get_my_twin_id(), + } as FilterOptions); + if (gatewayNodes.length == 0) throw new Error("No nodes available to complete this test"); + const GatewayNode = gatewayNodes[generateInt(0, gatewayNodes.length - 1)]; + + // Node Selection + const nodes = await gridClient.capacity.filterNodes({ + features: [Features.wireguard, Features.mycelium], + cru: cpu, + mru: memory, + sru: rootfsSize + diskSize, + farmId: 1, + availableFor: await gridClient.twins.get_my_twin_id(), + } as FilterOptions); + const nodeId = await getOnlineNode(nodes); + if (nodeId == -1) throw new Error("No nodes available to complete this test"); + const domain = name + "." + GatewayNode.publicConfig.domain; + + // VM Model + const vms: MachinesModel = { + name: deploymentName, + network: { + name: networkName, + ip_range: ipRange, + }, + machines: [ + { + name: vmName, + node_id: nodeId, + cpu: cpu, + memory: 1024 * memory, + rootfs_size: rootfsSize, + disks: [ + { + name: diskName, + size: diskSize, + mountpoint: mountPoint, + }, + ], + flist: "https://hub.grid.tf/tf-official-apps/jitsi-latest.flist", + entrypoint: "/sbin/zinit init", + public_ip: publicIp, + planetary: true, + mycelium: true, + env: { + SSH_KEY: config.ssh_key, + JITSI_HOSTNAME: domain, + }, + }, + ], + metadata: metadata, + description: description, + }; + + const res = await gridClient.machines.deploy(vms); + log(res); + + // Contracts Assertions + expect(res.contracts.created).toHaveLength(1); + expect(res.contracts.updated).toHaveLength(0); + expect(res.contracts.deleted).toHaveLength(0); + + const result = await gridClient.machines.getObj(vms.name); + log(result); + + // Gateway Backend Configuration + const backends = ["http://[" + result[0].planetary + "]:80"]; + log(backends); + + // Gateway Model + const gw: GatewayNameModel = { + name: name, + node_id: GatewayNode.nodeId, + tls_passthrough: tlsPassthrough, + backends: backends, + }; + + const gatewayRes = await gridClient.gateway.deploy_name(gw); + log(gatewayRes); + + // Gateway Assertions + expect(gatewayRes.contracts.created).toHaveLength(1); + + const gatewayResult = await gridClient.gateway.getObj(gw.name); + log(gatewayResult); + + // Gateway Assertions + expect(gatewayResult[0].name).toBe(name); + expect(gatewayResult[0].backends).toStrictEqual(backends); + + // Gateway reachability check + const site = "http://" + gatewayResult[0].domain + "/"; + log(`Testing Gateway URL: ${site}`); + let reachable = false; + + for (let i = 0; i <= 250; i++) { + const wait = await setTimeout(5000, "Waiting for gateway to be ready"); + log(wait); + + await axios + .get(site) + .then(res => { + log("Gateway is reachable"); + log(res.status); + log(res.statusText); + expect(res.status).toBe(200); + reachable = true; + }) + .catch(() => { + log("Gateway is not reachable"); + }); + if (reachable) break; + if (i === 250) throw new Error("Gateway is unreachable after retries"); + } +}); + +afterAll(async () => { + const vmNames = await gridClient.machines.list(); + for (const name of vmNames) { + const res = await gridClient.machines.delete({ name }); + log(res); + } + + const gwNames = await gridClient.gateway.list(); + for (const name of gwNames) { + const res = await gridClient.gateway.delete_name({ name }); + log(res); + } + + return await gridClient.disconnect(); +}, 130000); diff --git a/packages/grid_client/tests/modules/applications/nostr.test.ts b/packages/grid_client/tests/modules/applications/nostr.test.ts new file mode 100644 index 0000000000..4a84aebe29 --- /dev/null +++ b/packages/grid_client/tests/modules/applications/nostr.test.ts @@ -0,0 +1,237 @@ +import axios from "axios"; +import { setTimeout } from "timers/promises"; + +import { + Features, + FilterOptions, + GatewayNameModel, + generateString, + GridClient, + MachinesModel, + randomChoice, +} from "../../../src"; +import { config, getClient } from "../../client_loader"; +import { generateInt, getOnlineNode, log } from "../../utils"; + +jest.setTimeout(1250000); + +let gridClient: GridClient; + +beforeAll(async () => { + gridClient = await getClient(); + return gridClient; +}); + +async function deploy(client: GridClient, vms: MachinesModel, subdomain: string, gatewayNode: any) { + // Deploy VM + const resultVM = await client.machines.deploy(vms); + log("================= Deploying VM ================="); + log(resultVM); + log("================= Deploying VM ================="); + + // Get WG interface details + const wgnet = (await client.machines.getObj(vms.name))[0].interfaces[0]; + + // Deploy Gateway + const gateway: GatewayNameModel = { + name: subdomain, + network: wgnet.network, + node_id: gatewayNode.nodeId, + tls_passthrough: false, + backends: [`http://${wgnet.ip}:8080`], + }; + + const resultGateway = await client.gateway.deploy_name(gateway); + log("================= Deploying Gateway ================="); + log(resultGateway); + log("================= Deploying Gateway ================="); +} + +async function getDeployment(client: GridClient, name: string, subdomain: string) { + // Get VM deployment + const resultVM = await client.machines.getObj(name); + log("================= Getting VM Deployment ================="); + log(resultVM); + log("================= Getting VM Deployment ================="); + + // Get Gateway deployment + const resultGateway = await client.gateway.getObj(subdomain); + log("================= Getting Gateway Deployment ================="); + log(resultGateway); + log(`https://${resultGateway[0].domain}`); + log("================= Getting Gateway Deployment ================="); +} + +async function cancel(client: GridClient, name: string, subdomain: string) { + // Cancel VM deployment + const resultVM = await client.machines.delete({ name }); + log("================= Canceling VM Deployment ================="); + log(resultVM); + log("================= Canceling VM Deployment ================="); + + // Cancel Gateway deployment + const resultGateway = await client.gateway.delete_name({ name: subdomain }); + log("================= Canceling Gateway Deployment ================="); + log(resultGateway); + log("================= Canceling Gateway Deployment ================="); +} +test("TCXXXX - Applications: Deploy Nostr with WireGuard", async () => { + /********************************************** + Test Suite: Grid3_Client_TS (Automated) + Test Cases: TCXXXX - Applications: Deploy Nostr with WireGuard + Scenario: + - Generate Test Data/Nostr Config/Gateway Config. + - Select a Node To Deploy the Nostr on. + - Select a Gateway Node To Deploy the gateway on. + - Deploy the Nostr solution. + - Assert that the generated data matches + the deployment details. + - Pass the WireGuard IP of the Created Nostr instance + to the Gateway Config. + - Deploy the Gateway. + - Assert that the generated data matches + the deployment details. + - Assert that the Gateway points at the WireGuard IP + of the created Nostr. + - Assert that the returned domain is working + and returns correct data. + **********************************************/ + + // Test Data + const name = "gw" + generateString(10).toLowerCase(); + const tlsPassthrough = false; + const cpu = 2; + const memory = 4; + const rootfsSize = 0; + const diskSize = 50; + const networkName = generateString(15); + const vmName = generateString(15); + const diskName = generateString(15); + const mountPoint = "/mnt/data"; + const publicIp = false; + const ipRange = "10.252.0.0/16"; + const metadata = "{'deploymentType': 'nostr'}"; + const description = "Test deploying Nostr via ts grid3 client with WireGuard"; + + // Gateway Node Selection + const gatewayNodes = await gridClient.capacity.filterNodes({ + features: [Features.wireguard, Features.mycelium], + gateway: true, + farmId: 1, + availableFor: await gridClient.twins.get_my_twin_id(), + } as FilterOptions); + if (gatewayNodes.length === 0) throw new Error("No nodes available to complete this test"); + const GatewayNode = gatewayNodes[generateInt(0, gatewayNodes.length - 1)]; + + // Node Selection + const nodes = await gridClient.capacity.filterNodes({ + features: [Features.wireguard, Features.mycelium], + cru: cpu, + mru: memory, + sru: rootfsSize + diskSize, + farmId: 1, + availableFor: await gridClient.twins.get_my_twin_id(), + } as FilterOptions); + const nodeId = await getOnlineNode(nodes); + if (nodeId === -1) throw new Error("No nodes available to complete this test"); + + // VM Model + const vms: MachinesModel = { + name: name, + network: { + name: networkName, + ip_range: ipRange, + }, + machines: [ + { + name: vmName, + node_id: nodeId, + cpu: cpu, + memory: 1024 * memory, + rootfs_size: rootfsSize, + disks: [ + { + name: diskName, + size: diskSize, + mountpoint: mountPoint, + }, + ], + flist: "https://hub.grid.tf/tf-official-apps/nostr_relay-mycelium.flist", + entrypoint: "/sbin/zinit init", + public_ip: publicIp, + planetary: false, // Planetary disabled + mycelium: true, + env: { + SSH_KEY: config.ssh_key, + }, + }, + ], + metadata: metadata, + description: description, + }; + + const res = await gridClient.machines.deploy(vms); + log(res); + + // Contracts Assertions + expect(res.contracts.created).toHaveLength(1); + expect(res.contracts.updated).toHaveLength(0); + expect(res.contracts.deleted).toHaveLength(0); + + const result = await gridClient.machines.getObj(vms.name); + log(result); + + // Retrieve the WireGuard network details of the VM + const wgnet = result[0].interfaces[0]; + + // Gateway Backend Configuration + const backends = [`http://${wgnet.ip}:8080`]; + log(backends); + + // Gateway Model + const gw: GatewayNameModel = { + name: name, + network: wgnet.network, + node_id: GatewayNode.nodeId, + tls_passthrough: tlsPassthrough, + backends: backends, + }; + + const gatewayRes = await gridClient.gateway.deploy_name(gw); + log(gatewayRes); + + // Gateway Assertions + expect(gatewayRes.contracts.created).toHaveLength(1); + + const gatewayResult = await gridClient.gateway.getObj(gw.name); + log(gatewayResult); + + // Gateway Assertions + expect(gatewayResult[0].name).toBe(name); + expect(gatewayResult[0].backends).toStrictEqual(backends); + + // Gateway reachability check + const site = `http://${wgnet.ip}:8080/`; + log(`Testing Gateway URL: ${site}`); + let reachable = false; + + for (let i = 0; i <= 250; i++) { + const wait = await setTimeout(5000, "Waiting for gateway to be ready"); + log(wait); + + await axios + .get(site) + .then(res => { + log("Gateway is reachable"); + log(res.status); + log(res.statusText); + expect(res.status).toBe(200); + reachable = true; + }) + .catch(() => { + log("Gateway is not reachable"); + }); + if (reachable) break; + if (i === 250) throw new Error("Gateway is unreachable after retries"); + } +});