Skip to content

Commit 8f60a03

Browse files
committed
fix missing deps by removing it
1 parent b8778dd commit 8f60a03

File tree

6 files changed

+379
-22
lines changed

6 files changed

+379
-22
lines changed

bun.lock

Lines changed: 9 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "hivessh",
3-
"version": "1.5.1",
3+
"version": "1.5.2",
44
"description": "HiveSsh is an innovative library designed to streamline SSH2 connections and simplify task execution on Linux servers.",
55
"type": "module",
66
"main": "./dist/index.cjs",
@@ -61,12 +61,12 @@
6161
},
6262
"license": "MIT",
6363
"devDependencies": {
64-
"@types/ssh2": "^1.15.0",
65-
"nodemon": "^3.1.0",
66-
"typescript": "^5.4.3",
67-
"undici": "^7.4.0"
64+
"@types/ssh2": "^1.15.5",
65+
"nodemon": "^3.1.10",
66+
"typescript": "^5.9.2",
67+
"undici": "^7.15.0"
6868
},
6969
"dependencies": {
70-
"ssh2": "^1.15.0"
70+
"ssh2": "^1.17.0"
7171
}
72-
}
72+
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import { afterEach, beforeEach, describe, expect, test } from "bun:test"
2+
import { OsRelease } from "../../essentials/OsRelease.js"
3+
import { SshHost } from "../../index.js"
4+
import { connectTestHosts, loadEnvVars, TestHost } from "./e2eTestBase.js"
5+
6+
const toolsToCheck: string[] = [
7+
"ls",
8+
"cat",
9+
"neofetch",
10+
"vim",
11+
"nano",
12+
"git",
13+
"curl",
14+
"wget",
15+
"ssh",
16+
"scp",
17+
"tar",
18+
"gzip",
19+
"zip",
20+
"unzip",
21+
"7z",
22+
"unrar",
23+
"btop",
24+
"htop",
25+
"top",
26+
"ufw",
27+
]
28+
29+
let testSshHosts: [TestHost, SshHost][] = []
30+
31+
describe("e2e concurrent exec", () => {
32+
beforeEach(async () => {
33+
const hostData = loadEnvVars()
34+
if (hostData.length == 0) {
35+
throw new Error("No hosts configured!")
36+
}
37+
38+
testSshHosts = await connectTestHosts(hostData)
39+
})
40+
41+
afterEach(async () => {
42+
await Promise.all(
43+
testSshHosts.map(
44+
([testHost, host]) => host.disconnect()
45+
)
46+
)
47+
})
48+
49+
test("execute sleep tasks", async () => {
50+
await Promise.all(
51+
testSshHosts.map(
52+
([testHost, host]) => executeSleepWorkload(host)
53+
)
54+
)
55+
}, 1000 * 20)
56+
57+
test("execute host info tasks", async () => {
58+
for (const testHost of testSshHosts) {
59+
const info = await collectHostInfo(
60+
testHost[1],
61+
toolsToCheck,
62+
)
63+
64+
// osRelease
65+
expect(info.osRelease.distroName.length).toBeGreaterThan(0)
66+
expect(info.osRelease.distroVersion.length).toBeGreaterThan(0)
67+
expect(info.toolesInstalled.length).toBeGreaterThan(0)
68+
69+
expect(info.homefiles.length).toBeGreaterThan(0)
70+
expect(info.homedir.length).toBeGreaterThan(0)
71+
}
72+
}, 1000 * 20)
73+
})
74+
75+
76+
export interface HostInfo {
77+
sshHost: SshHost,
78+
osRelease: OsRelease,
79+
toolesInstalled: string[],
80+
neofetch: string | undefined,
81+
homefiles: string[],
82+
homedir: string,
83+
}
84+
85+
/**
86+
* Collects information about a host and returns it in the form of a HostInfo object.
87+
*
88+
* The function fetches the host's OS release, checks for the presence of the given tools,
89+
* lists the files in the user's home directory, and determines the user's home directory path.
90+
*
91+
* @param host The SshHost object to collect information about.
92+
* @param toolsToCheck An array of strings, each containing the name of a command-line tool to check for.
93+
* @returns A Promise resolving to a HostInfo object containing the collected host information.
94+
*/
95+
export async function collectHostInfo(host: SshHost, toolsToCheck: string[]): Promise<HostInfo> {
96+
const hostInfo: HostInfo = {
97+
sshHost: host,
98+
osRelease: await host.fetchOsRelease(),
99+
toolesInstalled: [],
100+
neofetch: undefined,
101+
homefiles: [],
102+
homedir: await host.homeDir(),
103+
}
104+
105+
hostInfo.homefiles = (await host.sftp.readdir(hostInfo.homedir)).map(
106+
(stat) => stat.filename,
107+
)
108+
109+
for (const tool of toolsToCheck) {
110+
if (await host.cmdExists(tool)) {
111+
hostInfo.toolesInstalled.push(tool)
112+
}
113+
114+
}
115+
116+
return hostInfo
117+
}
118+
119+
/**
120+
* Executes a series of commands on a given SSH host, alternating between
121+
* listing directory contents and sleeping for increasing durations.
122+
*
123+
* The function runs the "ls -al" command to list all files in the current
124+
* directory, then pauses execution with the "sleep" command for 1 second,
125+
* 2 seconds, and 3 seconds, respectively, between each directory listing.
126+
*
127+
* @param host The SshHost object on which to execute the commands.
128+
* @returns A Promise that resolves when all commands have been executed.
129+
*/
130+
export async function executeSleepWorkload(
131+
host: SshHost,
132+
): Promise<void> {
133+
await host.exec("ls -al")
134+
await host.exec("sleep 1")
135+
await host.exec("ls -al")
136+
await host.exec("sleep 2")
137+
await host.exec("ls -al")
138+
await host.exec("sleep 3")
139+
await host.exec("ls -al")
140+
}

src/test/e2e/e2eTestBase.ts

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { SshHost } from "../../index.js"
2+
3+
export interface TestHost {
4+
id: number,
5+
host: string,
6+
user: string,
7+
port: number,
8+
privateKeyPath: string
9+
}
10+
11+
/**
12+
* Loads host configuration from environment variables and returns an array of TestHost objects.
13+
*
14+
* The function iterates over environment variables to find host configurations following the
15+
* pattern `TEST_HOST1`, `TEST_HOST2`, etc., appending the details for each host into an array.
16+
* If any required environment variable for a host is not set, an error is thrown.
17+
*
18+
* @throws Will throw an error if any of the required environment variables (_HOST, _USER, _PORT, _KEYPATH)
19+
* for a host are not set.
20+
* @returns An array of TestHost objects, each containing the host's id, hostname, username, port,
21+
* and private key path.
22+
*/
23+
export function loadEnvVars(): TestHost[] {
24+
let i = 1
25+
const hosts: TestHost[] = []
26+
while (true) {
27+
const key = "TEST_HOST" + i
28+
const host: TestHost = {
29+
id: i - 1,
30+
host: process.env[key + "_HOST"] ?? "",
31+
user: process.env[key + "_USER"] ?? "",
32+
port: Number(process.env[key + "_PORT"]),
33+
privateKeyPath: process.env[key + "_KEYPATH"] ?? "",
34+
}
35+
36+
if (
37+
host.host.length == 0
38+
&& host.user.length == 0
39+
&& isNaN(host.port)
40+
&& host.privateKeyPath.length == 0
41+
) {
42+
break
43+
}
44+
45+
if (host.host.length == 0) {
46+
throw new Error("Env var " + key + "_HOST not set: " + JSON.stringify(host))
47+
} else if (host.user.length == 0) {
48+
throw new Error("Env var " + key + "_USER not set: " + JSON.stringify(host))
49+
} else if (isNaN(host.port)) {
50+
throw new Error("Env var " + key + "_PORT not set: " + JSON.stringify(host))
51+
} else if (host.privateKeyPath.length == 0) {
52+
throw new Error("Env var " + key + "_KEYPATH not set: " + JSON.stringify(host))
53+
}
54+
55+
host.privateKeyPath =
56+
host.privateKeyPath
57+
.split("$HOME")
58+
.join(process.env.HOME)
59+
60+
hosts.push(host)
61+
62+
i++
63+
}
64+
65+
return hosts
66+
}
67+
68+
/**
69+
* Connects to all hosts in the given array and returns a Promise resolving to an array of
70+
* tuples, each containing the host configuration and the connected SshHost object.
71+
*
72+
* @param hostData An array of TestHost objects, each containing the host's id, hostname,
73+
* username, port, and private key path.
74+
*
75+
* @returns A Promise resolving to an array of tuples, each containing the host configuration
76+
* and the connected SshHost object.
77+
*/
78+
export function connectTestHosts(
79+
hostData: TestHost[],
80+
): Promise<[TestHost, SshHost][]> {
81+
return Promise.all(
82+
hostData.map(async (hostData) => {
83+
const host = await SshHost.connect({
84+
host: hostData.host,
85+
user: hostData.user,
86+
port: hostData.port,
87+
privateKeyPath: hostData.privateKeyPath,
88+
})
89+
90+
return [hostData, host]
91+
})
92+
)
93+
}

0 commit comments

Comments
 (0)