-
Notifications
You must be signed in to change notification settings - Fork 8
Add peertube, funkwhale and casperlabs automated tests to the grid client using jest #2784
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
A-Harby
merged 7 commits into
development
from
development_add_casperlabs_automated_test
Jun 10, 2024
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
80a5397
add casperlabs automated test using jest
A-Harby 53b7dcb
add peertube and funkwhale tests
A-Harby 620682b
apply capacity resources and improve code
A-Harby f51fae7
fix timeout and site call header
A-Harby 9af69eb
improve code and comments
A-Harby d3bdda7
add rootfs disk and check for it
A-Harby d87b135
remove unused after each
A-Harby File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
240 changes: 240 additions & 0 deletions
240
packages/grid_client/tests/modules/applications/casperlabs.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,240 @@ | ||
import axios from "axios"; | ||
import { setTimeout } from "timers/promises"; | ||
|
||
import { FilterOptions, GatewayNameModel, generateString, GridClient, MachinesModel, randomChoice } from "../../../src"; | ||
import { config, getClient } from "../../client_loader"; | ||
import { bytesToGB, generateInt, getOnlineNode, log, splitIP } from "../../utils"; | ||
|
||
jest.setTimeout(900000); | ||
|
||
let gridClient: GridClient; | ||
let deploymentName: string; | ||
|
||
beforeAll(async () => { | ||
gridClient = await getClient(); | ||
deploymentName = "cl" + generateString(10); | ||
gridClient.clientOptions.projectName = `casperlabs/${deploymentName}`; | ||
gridClient._connect(); | ||
return gridClient; | ||
}); | ||
|
||
//Private IP Regex | ||
const ipRegex = /(^127\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)/; | ||
|
||
test("TC2683 - Applications: Deploy Casperlabs", async () => { | ||
/********************************************** | ||
Test Suite: Grid3_Client_TS (Automated) | ||
Test Cases: TC2683 - Applications: Deploy Casperlabs | ||
Scenario: | ||
- Generate Test Data/casperlabs Config/Gateway Config. | ||
- Select a Node To Deploy the casperlabs on. | ||
- Select a Gateway Node To Deploy the gateway on. | ||
- Deploy the casperlabs solution. | ||
- Assert that the generated data matches | ||
the deployment details. | ||
- Pass the IP of the Created casperlabs 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 casperlabs. | ||
- 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 = 2; | ||
const diskSize = 100; | ||
const networkName = generateString(15); | ||
const vmName = generateString(15); | ||
const diskName = generateString(15); | ||
const mountPoint = "/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': 'casperlabs'}"; | ||
const description = "test deploying Casperlabs via ts grid3 client"; | ||
|
||
//GatewayNode Selection | ||
const gatewayNodes = await gridClient.capacity.filterNodes({ | ||
gateway: true, | ||
farmId: 1, | ||
availableFor: await gridClient.twins.get_my_twin_id(), | ||
} as FilterOptions); | ||
if (gatewayNodes.length == 0) throw new Error("no gateway nodes available to complete this test"); | ||
const GatewayNode = gatewayNodes[generateInt(0, gatewayNodes.length - 1)]; | ||
|
||
//Node Selection | ||
const nodes = await gridClient.capacity.filterNodes({ | ||
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/casperlabs-latest.flist", | ||
entrypoint: "/sbin/zinit init", | ||
public_ip: publicIp, | ||
planetary: true, | ||
mycelium: false, | ||
env: { | ||
SSH_KEY: config.ssh_key, | ||
CASPERLABS_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 vmsList = await gridClient.machines.list(); | ||
log(vmsList); | ||
|
||
//VM List Assertions | ||
expect(vmsList.length).toBeGreaterThanOrEqual(1); | ||
expect(vmsList).toContain(vms.name); | ||
|
||
const result = await gridClient.machines.getObj(vms.name); | ||
log(result); | ||
|
||
//VM Assertions | ||
expect(result[0].nodeId).toBe(nodeId); | ||
expect(result[0].status).toBe("ok"); | ||
expect(result[0].flist).toBe(vms.machines[0].flist); | ||
expect(result[0].entrypoint).toBe(vms.machines[0].entrypoint); | ||
expect(result[0].mounts).toHaveLength(1); | ||
expect(result[0].interfaces[0]["network"]).toBe(vms.network.name); | ||
expect(result[0].interfaces[0]["ip"]).toContain(splitIP(vms.network.ip_range)); | ||
expect(result[0].interfaces[0]["ip"]).toMatch(ipRegex); | ||
expect(result[0].capacity["cpu"]).toBe(cpu); | ||
expect(result[0].capacity["memory"]).toBe(memory * 1024); | ||
expect(result[0].planetary).toBeDefined(); | ||
expect(result[0].publicIP).toBeNull(); | ||
expect(result[0].description).toBe(description); | ||
expect(result[0].rootfs_size).toBe(bytesToGB(rootfsSize)); | ||
expect(result[0].mounts[0]["name"]).toBe(diskName); | ||
expect(result[0].mounts[0]["size"]).toBe(bytesToGB(diskSize)); | ||
expect(result[0].mounts[0]["mountPoint"]).toBe(mountPoint); | ||
expect(result[0].mounts[0]["state"]).toBe("ok"); | ||
|
||
const backends = ["http://[" + result[0].planetary + "]:80"]; | ||
log(backends); | ||
|
||
//Name 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); | ||
|
||
//Contracts Assertions | ||
expect(gatewayRes.contracts.created).toHaveLength(1); | ||
expect(gatewayRes.contracts.updated).toHaveLength(0); | ||
expect(gatewayRes.contracts.deleted).toHaveLength(0); | ||
expect(gatewayRes.contracts.created[0].contractType.nodeContract.nodeId).toBe(GatewayNode.nodeId); | ||
|
||
const gatewayResult = await gridClient.gateway.getObj(gw.name); | ||
log(gatewayResult); | ||
|
||
//Gateway Assertions | ||
expect(gatewayResult[0].name).toBe(name); | ||
expect(gatewayResult[0].status).toBe("ok"); | ||
expect(gatewayResult[0].type).toContain("name"); | ||
expect(gatewayResult[0].domain).toContain(name); | ||
expect(gatewayResult[0].tls_passthrough).toBe(tlsPassthrough); | ||
expect(gatewayResult[0].backends).toStrictEqual(backends); | ||
|
||
const site = "https://" + gatewayResult[0].domain; | ||
let reachable = false; | ||
|
||
for (let i = 0; i < 180; 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); | ||
log(res.data); | ||
expect(res.status).toBe(200); | ||
expect(res.statusText).toBe("OK"); | ||
expect(res.data).toContain("Your Casper node is now running succesfully on the ThreeFold Grid."); | ||
reachable = true; | ||
}) | ||
.catch(() => { | ||
log("gateway is not reachable"); | ||
}); | ||
if (reachable) { | ||
break; | ||
} else if (i == 180) { | ||
throw new Error("Gateway is unreachable after multiple retries"); | ||
} | ||
} | ||
}); | ||
|
||
afterAll(async () => { | ||
const vmNames = await gridClient.machines.list(); | ||
for (const name of vmNames) { | ||
const res = await gridClient.machines.delete({ name }); | ||
log(res); | ||
expect(res.created).toHaveLength(0); | ||
expect(res.updated).toHaveLength(0); | ||
expect(res.deleted).toBeDefined(); | ||
} | ||
|
||
const gwNames = await gridClient.gateway.list(); | ||
for (const name of gwNames) { | ||
const res = await gridClient.gateway.delete_name({ name }); | ||
log(res); | ||
expect(res.created).toHaveLength(0); | ||
expect(res.updated).toHaveLength(0); | ||
expect(res.deleted).toBeDefined(); | ||
} | ||
|
||
return await gridClient.disconnect(); | ||
}, 130000); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.