ssh-client-wrapper 2.2.3 → 2.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +1 -0
- package/.eslintrc.json +24 -153
- package/Dockerfile +4 -6
- package/Dockerfile-bullseye +7 -0
- package/Dockerfile-buster +7 -0
- package/README.md +0 -6
- package/docker-compose.yml +23 -3
- package/lib/fork.js +12 -12
- package/lib/index.js +11 -41
- package/lib/rsyncExec.js +9 -9
- package/lib/sshExec.js +23 -23
- package/lib/util.js +17 -14
- package/package.json +8 -7
- package/run_test_all.sh +11 -0
- package/test/interface.js +48 -50
- package/test/rsyncExec.js +72 -73
- package/test/sshExec.js +40 -40
- package/test/testUtil/testFiles.js +7 -8
- package/test/util.js +12 -13
package/lib/sshExec.js
CHANGED
|
@@ -14,7 +14,7 @@ const { fork, createMasterPty, sshLoginCallback } = require("./fork.js");
|
|
|
14
14
|
* @param {number} timeout - timeout (in sec.)
|
|
15
15
|
* @param {Function} outputCallback - Callback routine for stdout and stderr.
|
|
16
16
|
*/
|
|
17
|
-
async function sshExec(hostInfo, cmd, timeout, outputCallback) {
|
|
17
|
+
async function sshExec (hostInfo, cmd, timeout, outputCallback) {
|
|
18
18
|
debug("sshExec called");
|
|
19
19
|
await connect(hostInfo);
|
|
20
20
|
debug("exec", cmd, "on remote server");
|
|
@@ -46,14 +46,14 @@ async function sshExec(hostInfo, cmd, timeout, outputCallback) {
|
|
|
46
46
|
* @param {Object} hostInfo - hostinfo object
|
|
47
47
|
* @param {Integer} timeout - timeout in secconds
|
|
48
48
|
*/
|
|
49
|
-
async function canConnect(hostInfo, timeout = 60) {
|
|
49
|
+
async function canConnect (hostInfo, timeout = 60) {
|
|
50
50
|
debug("canConnect called");
|
|
51
51
|
sanityCheck(hostInfo);
|
|
52
52
|
|
|
53
53
|
await connect(hostInfo, timeout);
|
|
54
54
|
await disconnect(hostInfo);
|
|
55
|
-
//if connection fail, Error is throwed.
|
|
56
|
-
//so, if we reach here, connection must be succeeded
|
|
55
|
+
// if connection fail, Error is throwed.
|
|
56
|
+
// so, if we reach here, connection must be succeeded
|
|
57
57
|
return true;
|
|
58
58
|
}
|
|
59
59
|
|
|
@@ -62,13 +62,13 @@ async function canConnect(hostInfo, timeout = 60) {
|
|
|
62
62
|
* @param {Object} hostInfo - hostinfo object
|
|
63
63
|
* @returns {boolean} - true if master session exists
|
|
64
64
|
*/
|
|
65
|
-
async function existsMaster(hostInfo, argTimeout) {
|
|
65
|
+
async function existsMaster (hostInfo, argTimeout) {
|
|
66
66
|
debugVerbose("existsMaster called");
|
|
67
67
|
const args = getSshOption(hostInfo);
|
|
68
68
|
args.push("-Ocheck");
|
|
69
69
|
|
|
70
70
|
let output = "";
|
|
71
|
-
const cb = (e)=>{
|
|
71
|
+
const cb = (e) => {
|
|
72
72
|
output += e;
|
|
73
73
|
};
|
|
74
74
|
|
|
@@ -94,7 +94,7 @@ async function existsMaster(hostInfo, argTimeout) {
|
|
|
94
94
|
* create master ssh connection
|
|
95
95
|
* @param {Object} hostInfo - hostinfo object
|
|
96
96
|
*/
|
|
97
|
-
async function connect(hostInfo, timeout = 60) {
|
|
97
|
+
async function connect (hostInfo, timeout = 60) {
|
|
98
98
|
debug("connect called");
|
|
99
99
|
|
|
100
100
|
if (await existsMaster(hostInfo, timeout)) {
|
|
@@ -110,8 +110,8 @@ async function connect(hostInfo, timeout = 60) {
|
|
|
110
110
|
const re = new RegExp(`^${words}`);
|
|
111
111
|
|
|
112
112
|
let ac = null;
|
|
113
|
-
const p = new Promise((resolve, reject)=>{
|
|
114
|
-
ac = watchDogTimer(timeout, "make connection", ()=>{
|
|
113
|
+
const p = new Promise((resolve, reject) => {
|
|
114
|
+
ac = watchDogTimer(timeout, "make connection", () => {
|
|
115
115
|
sendPty(hostInfo.masterPty, "\n", debugSendMasterPty, 137);
|
|
116
116
|
sendPty(hostInfo.masterPty, "exit\n", debugSendMasterPty, 138);
|
|
117
117
|
|
|
@@ -123,9 +123,9 @@ async function connect(hostInfo, timeout = 60) {
|
|
|
123
123
|
});
|
|
124
124
|
|
|
125
125
|
let done = false;
|
|
126
|
-
hostInfo.masterPty.onData((data)=>{
|
|
126
|
+
hostInfo.masterPty.onData((data) => {
|
|
127
127
|
if (done) {
|
|
128
|
-
//safeguard
|
|
128
|
+
// safeguard
|
|
129
129
|
return;
|
|
130
130
|
}
|
|
131
131
|
const output = data.toString();
|
|
@@ -145,12 +145,12 @@ async function connect(hostInfo, timeout = 60) {
|
|
|
145
145
|
reject(new Error("Operation timed out"));
|
|
146
146
|
}
|
|
147
147
|
});
|
|
148
|
-
hostInfo.masterPty.onData((data)=>{
|
|
148
|
+
hostInfo.masterPty.onData((data) => {
|
|
149
149
|
const output = data.toString();
|
|
150
150
|
sshLoginCallback(output, hostInfo.masterPty, hostInfo.password, hostInfo.passphrase, debugSendMasterPty)
|
|
151
151
|
.catch(reject);
|
|
152
152
|
});
|
|
153
|
-
hostInfo.masterPty.onExit((e)=>{
|
|
153
|
+
hostInfo.masterPty.onExit((e) => {
|
|
154
154
|
debug("master pty exit", e);
|
|
155
155
|
resolve(e);
|
|
156
156
|
});
|
|
@@ -175,7 +175,7 @@ async function connect(hostInfo, timeout = 60) {
|
|
|
175
175
|
* remove master session
|
|
176
176
|
* @param {Object} hostInfo - hostinfo object
|
|
177
177
|
*/
|
|
178
|
-
async function disconnect(hostInfo) {
|
|
178
|
+
async function disconnect (hostInfo) {
|
|
179
179
|
debug("disconnect called");
|
|
180
180
|
|
|
181
181
|
if (await existsMaster(hostInfo)) {
|
|
@@ -183,7 +183,7 @@ async function disconnect(hostInfo) {
|
|
|
183
183
|
args.push("-Oexit");
|
|
184
184
|
|
|
185
185
|
let output = "";
|
|
186
|
-
const cb = (e)=>{
|
|
186
|
+
const cb = (e) => {
|
|
187
187
|
output += e;
|
|
188
188
|
};
|
|
189
189
|
try {
|
|
@@ -218,20 +218,21 @@ async function disconnect(hostInfo) {
|
|
|
218
218
|
* @param {number} timeout - timeout (in sec.)
|
|
219
219
|
* @returns {string[]} - output from ls
|
|
220
220
|
*/
|
|
221
|
-
async function ls(hostInfo, target, lsOpt, timeout) {
|
|
221
|
+
async function ls (hostInfo, target, lsOpt, timeout) {
|
|
222
222
|
debug("ls called");
|
|
223
223
|
const outputArray = [];
|
|
224
224
|
try {
|
|
225
|
-
await sshExec(hostInfo, `ls ${lsOpt.join(" ")} ${target}`, timeout, (data)=>{
|
|
225
|
+
await sshExec(hostInfo, `ls ${lsOpt.join(" ")} ${target}`, timeout, (data) => {
|
|
226
226
|
outputArray.push(data);
|
|
227
227
|
});
|
|
228
228
|
} catch (e) {
|
|
229
|
-
//non-zero retrun should be allowed
|
|
229
|
+
// non-zero retrun should be allowed
|
|
230
230
|
if (typeof e.rt === "undefined" || e.rt < 0) {
|
|
231
231
|
throw e;
|
|
232
232
|
}
|
|
233
233
|
}
|
|
234
|
-
return outputArray.length === 0
|
|
234
|
+
return outputArray.length === 0
|
|
235
|
+
? []
|
|
235
236
|
: outputArray
|
|
236
237
|
.join("\n")
|
|
237
238
|
.replace(/\n+/g, "\n")
|
|
@@ -243,13 +244,13 @@ async function ls(hostInfo, target, lsOpt, timeout) {
|
|
|
243
244
|
* retry fork() if it throw retryable error
|
|
244
245
|
* @param {Function} func - function to be wrapped
|
|
245
246
|
*/
|
|
246
|
-
async function retryWrapper(func, hostInfo) {
|
|
247
|
+
async function retryWrapper (func, hostInfo) {
|
|
247
248
|
const minTimeout = hostInfo.retryMinTimeout * 1000 || 1000;
|
|
248
249
|
const maxTimeout = hostInfo.retryMaxTimeout * 1000 || 5000;
|
|
249
250
|
const retries = hostInfo.maxRetry || 1;
|
|
250
|
-
return promiseRetry({ retries, minTimeout, maxTimeout }, (retry, number)=>{
|
|
251
|
+
return promiseRetry({ retries, minTimeout, maxTimeout }, (retry, number) => {
|
|
251
252
|
return func()
|
|
252
|
-
.catch((e)=>{
|
|
253
|
+
.catch((e) => {
|
|
253
254
|
if (e.retryable) {
|
|
254
255
|
debug(`retrying: ${number} times`);
|
|
255
256
|
disconnect(hostInfo).then(retry);
|
|
@@ -259,7 +260,6 @@ async function retryWrapper(func, hostInfo) {
|
|
|
259
260
|
});
|
|
260
261
|
}
|
|
261
262
|
|
|
262
|
-
|
|
263
263
|
module.exports = {
|
|
264
264
|
sshExec,
|
|
265
265
|
canConnect,
|
package/lib/util.js
CHANGED
|
@@ -25,7 +25,7 @@ const ajv = new Ajv({
|
|
|
25
25
|
});
|
|
26
26
|
require("ajv-keywords")(ajv, "transform");
|
|
27
27
|
|
|
28
|
-
//never validate password and passphrase value to avoid security insident
|
|
28
|
+
// never validate password and passphrase value to avoid security insident
|
|
29
29
|
const hostInfoSchema = {
|
|
30
30
|
type: "object",
|
|
31
31
|
properties: {
|
|
@@ -64,7 +64,7 @@ const validate = ajv.compile(hostInfoSchema);
|
|
|
64
64
|
* @param {Function} func - function
|
|
65
65
|
* @param {data} data - binary data which can be converted to string
|
|
66
66
|
*/
|
|
67
|
-
const buff2String = (func, data)=>{
|
|
67
|
+
const buff2String = (func, data) => {
|
|
68
68
|
func(data.toString().replace(/\r\n/g, EOL));
|
|
69
69
|
};
|
|
70
70
|
|
|
@@ -72,9 +72,12 @@ const buff2String = (func, data)=>{
|
|
|
72
72
|
* check if given hostInfo object is OK
|
|
73
73
|
* @param { Object } hostInfo - host information object defined in index.js
|
|
74
74
|
*/
|
|
75
|
-
const sanityCheck = (hostInfo)=>{
|
|
75
|
+
const sanityCheck = (hostInfo) => {
|
|
76
76
|
debug("sanityCheck called", hostInfo);
|
|
77
|
-
//keep password, passphrase, and masterPty
|
|
77
|
+
// keep password, passphrase, and masterPty before validate.
|
|
78
|
+
// these properties can have invalid value for JSON.
|
|
79
|
+
// ajv will remove that at validation pahse becase of additionalProperties setting
|
|
80
|
+
// so we keep them here and put back later.
|
|
78
81
|
const { password, passphrase, masterPty } = hostInfo;
|
|
79
82
|
validate(hostInfo);
|
|
80
83
|
|
|
@@ -96,7 +99,7 @@ const sanityCheck = (hostInfo)=>{
|
|
|
96
99
|
}
|
|
97
100
|
if (prop.startsWith("sshOpt")) {
|
|
98
101
|
debug("remove empty member of sshOpt");
|
|
99
|
-
hostInfo.sshOpt = hostInfo.sshOpt.filter((opt)=>{
|
|
102
|
+
hostInfo.sshOpt = hostInfo.sshOpt.filter((opt) => {
|
|
100
103
|
return opt !== "";
|
|
101
104
|
});
|
|
102
105
|
continue;
|
|
@@ -133,7 +136,7 @@ const sanityCheck = (hostInfo)=>{
|
|
|
133
136
|
* @param { Object} hostInfo - host information object defined in index.js
|
|
134
137
|
* @param {boolean} withoutDestination - return except for hostname
|
|
135
138
|
*/
|
|
136
|
-
const getSshOption = (hostInfo, withoutDestination)=>{
|
|
139
|
+
const getSshOption = (hostInfo, withoutDestination) => {
|
|
137
140
|
debug("getSshOption called");
|
|
138
141
|
const args = [];
|
|
139
142
|
|
|
@@ -186,19 +189,19 @@ const getSshOption = (hostInfo, withoutDestination)=>{
|
|
|
186
189
|
args.push(`-oConnectTimeout=${hostInfo.ConnectTimeout}`);
|
|
187
190
|
}
|
|
188
191
|
if (Array.isArray(hostInfo.sshOpt)) {
|
|
189
|
-
args.push(...hostInfo.sshOpt.filter((e)=>{
|
|
192
|
+
args.push(...hostInfo.sshOpt.filter((e) => {
|
|
190
193
|
return typeof e === "string";
|
|
191
194
|
}));
|
|
192
195
|
}
|
|
193
196
|
return args;
|
|
194
197
|
};
|
|
195
198
|
|
|
196
|
-
const isArrayOfString = (target)=>{
|
|
199
|
+
const isArrayOfString = (target) => {
|
|
197
200
|
if (!Array.isArray(target)) {
|
|
198
201
|
return false;
|
|
199
202
|
}
|
|
200
|
-
return !target.some((e)=>{
|
|
201
|
-
//target has non string member
|
|
203
|
+
return !target.some((e) => {
|
|
204
|
+
// target has non string member
|
|
202
205
|
return typeof e !== "string";
|
|
203
206
|
});
|
|
204
207
|
};
|
|
@@ -210,7 +213,7 @@ const isArrayOfString = (target)=>{
|
|
|
210
213
|
* @param {Function} logger - logging function
|
|
211
214
|
* @param {string} label - where this function is called
|
|
212
215
|
*/
|
|
213
|
-
const sendPty = async (pty, message, logger, label)=>{
|
|
216
|
+
const sendPty = async (pty, message, logger, label) => {
|
|
214
217
|
logger(`${label}: ${message}`);
|
|
215
218
|
pty.write(message);
|
|
216
219
|
};
|
|
@@ -222,15 +225,15 @@ const sendPty = async (pty, message, logger, label)=>{
|
|
|
222
225
|
* @param {Function} cb - call back function which will be called after timeout
|
|
223
226
|
* @returns {AbortController} - ac to stop watch dog timer
|
|
224
227
|
*/
|
|
225
|
-
const watchDogTimer = (timeout, label, cb)=>{
|
|
228
|
+
const watchDogTimer = (timeout, label, cb) => {
|
|
226
229
|
const ac = new AbortController();
|
|
227
230
|
const signal = ac.signal;
|
|
228
231
|
setTimeoutPromise(timeout * 1000, "neverUsedValue", { signal })
|
|
229
|
-
.then(()=>{
|
|
232
|
+
.then(() => {
|
|
230
233
|
debug(`can not finish ${label} within ${timeout} sec`);
|
|
231
234
|
return typeof cb === "function" ? cb() : true;
|
|
232
235
|
})
|
|
233
|
-
.catch((err)=>{
|
|
236
|
+
.catch((err) => {
|
|
234
237
|
if (err.name === "AbortError") {
|
|
235
238
|
debug(`timeout was aborted because ${label} has finished or canceled`);
|
|
236
239
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ssh-client-wrapper",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.6",
|
|
4
4
|
"description": "wrapper library for open ssh client and rsync",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ssh",
|
|
@@ -46,18 +46,19 @@
|
|
|
46
46
|
"chai-as-promised": "^7.1.1",
|
|
47
47
|
"chai-fs": "^2.0.0",
|
|
48
48
|
"eslint": "^8.38.0",
|
|
49
|
-
"eslint-config-
|
|
49
|
+
"eslint-config-standard": "^17.1.0",
|
|
50
50
|
"eslint-plugin-chai-expect": "^3.0.0",
|
|
51
|
-
"eslint-plugin-chai-friendly": "^0.7.
|
|
52
|
-
"eslint-plugin-
|
|
53
|
-
"eslint-plugin-
|
|
51
|
+
"eslint-plugin-chai-friendly": "^0.7.4",
|
|
52
|
+
"eslint-plugin-import": "^2.29.1",
|
|
53
|
+
"eslint-plugin-n": "^16.6.2",
|
|
54
|
+
"eslint-plugin-promise": "^6.1.1",
|
|
54
55
|
"fs-extra": "^11.1.1",
|
|
55
56
|
"husky": "^8.0.0",
|
|
56
57
|
"lint-staged": "^13.2.1",
|
|
57
58
|
"mocha": "^10.2.0",
|
|
58
|
-
"sinon": "^15.0.3",
|
|
59
|
-
"rewire": "^7.0.0",
|
|
60
59
|
"nyc": "^15.1.0",
|
|
60
|
+
"rewire": "^7.0.0",
|
|
61
|
+
"sinon": "^15.0.3",
|
|
61
62
|
"sinon-chai": "^3.7.0"
|
|
62
63
|
}
|
|
63
64
|
}
|
package/run_test_all.sh
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
docker-compose up testbed -d
|
|
3
|
+
export TEST_HOST=localhost
|
|
4
|
+
export TEST_USER=testuser
|
|
5
|
+
export TEST_PW=passw0rd
|
|
6
|
+
export TEST_PORT=4000
|
|
7
|
+
npm run test
|
|
8
|
+
docker-compose run --build --rm tester &&
|
|
9
|
+
docker-compose run --build --rm tester-bullseye &&
|
|
10
|
+
docker-compose run --build --rm tester-buster &&
|
|
11
|
+
docker-compose rm --stop --force testbed
|
package/test/interface.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
process.on("unhandledRejection", console.dir); //eslint-disable-line no-console
|
|
2
|
+
process.on("unhandledRejection", console.dir); // eslint-disable-line no-console
|
|
3
3
|
Error.traceLimit = 100000;
|
|
4
4
|
|
|
5
|
-
//setup test framework
|
|
5
|
+
// setup test framework
|
|
6
6
|
const chai = require("chai");
|
|
7
7
|
const { expect } = require("chai");
|
|
8
8
|
const sinon = require("sinon");
|
|
@@ -11,7 +11,7 @@ chai.use(require("chai-as-promised"));
|
|
|
11
11
|
|
|
12
12
|
const rewire = require("rewire");
|
|
13
13
|
|
|
14
|
-
//testee
|
|
14
|
+
// testee
|
|
15
15
|
const SshClientWrapper = rewire("../lib/index.js");
|
|
16
16
|
|
|
17
17
|
const sshExec = sinon.stub();
|
|
@@ -21,39 +21,37 @@ const ls = sinon.stub();
|
|
|
21
21
|
const send = sinon.stub();
|
|
22
22
|
const recv = sinon.stub();
|
|
23
23
|
|
|
24
|
-
//eslint-disable-next-line no-underscore-dangle
|
|
24
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
25
25
|
SshClientWrapper.__set__({
|
|
26
26
|
sshExec, canConnect, disconnect, ls, send, recv
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
describe("test for
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
//eslint-disable-next-line no-new
|
|
29
|
+
describe("test for interface", () => {
|
|
30
|
+
describe("test for constructor", () => {
|
|
31
|
+
it("should throw error when instanciate with non-empty string host", () => {
|
|
32
|
+
expect(() => {
|
|
33
|
+
// eslint-disable-next-line no-new
|
|
35
34
|
new SshClientWrapper({});
|
|
36
35
|
}).to.throw("host is required");
|
|
37
|
-
expect(()=>{
|
|
38
|
-
//eslint-disable-next-line no-new
|
|
36
|
+
expect(() => {
|
|
37
|
+
// eslint-disable-next-line no-new
|
|
39
38
|
new SshClientWrapper({ host: "" });
|
|
40
39
|
}).to.throw("empty host is not allowed");
|
|
41
40
|
});
|
|
42
|
-
it("should successfully instanciate only with host prop", ()=>{
|
|
41
|
+
it("should successfully instanciate only with host prop", () => {
|
|
43
42
|
expect(new SshClientWrapper({ host: "hoge" })).to.have.property("exec");
|
|
44
43
|
expect(new SshClientWrapper({ host: "hoge" })).to.have.property("ls");
|
|
45
|
-
expect(new SshClientWrapper({ host: "hoge" })).to.have.property("watch");
|
|
46
44
|
expect(new SshClientWrapper({ host: "hoge" })).to.have.property("send");
|
|
47
45
|
expect(new SshClientWrapper({ host: "hoge" })).to.have.property("recv");
|
|
48
46
|
expect(new SshClientWrapper({ host: "hoge" })).to.have.property("canConnect");
|
|
49
47
|
expect(new SshClientWrapper({ host: "hoge" })).to.have.property("disconnect");
|
|
50
48
|
});
|
|
51
49
|
});
|
|
52
|
-
describe("test for public method", ()=>{
|
|
50
|
+
describe("test for public method", () => {
|
|
53
51
|
let ssh;
|
|
54
52
|
const hostInfoOrg = { host: "hoge" };
|
|
55
53
|
const hostInfo = { ...hostInfoOrg, masterPty: null, rsyncVersion: null };
|
|
56
|
-
beforeEach(()=>{
|
|
54
|
+
beforeEach(() => {
|
|
57
55
|
ssh = new SshClientWrapper(hostInfoOrg);
|
|
58
56
|
sshExec.reset();
|
|
59
57
|
canConnect.reset();
|
|
@@ -62,113 +60,113 @@ describe("test for interface", ()=>{
|
|
|
62
60
|
send.reset();
|
|
63
61
|
recv.reset();
|
|
64
62
|
});
|
|
65
|
-
describe("test for exec", ()=>{
|
|
66
|
-
it("should call sshExec with cmd", ()=>{
|
|
63
|
+
describe("test for exec", () => {
|
|
64
|
+
it("should call sshExec with cmd", () => {
|
|
67
65
|
ssh.exec("ls");
|
|
68
66
|
expect(sshExec).to.be.calledWith(hostInfo, "ls", 0, null);
|
|
69
67
|
});
|
|
70
|
-
it("should call sshExec with cmd and timeout", ()=>{
|
|
68
|
+
it("should call sshExec with cmd and timeout", () => {
|
|
71
69
|
ssh.exec("ls", 10);
|
|
72
70
|
expect(sshExec).to.be.calledWith(hostInfo, "ls", 10, null);
|
|
73
71
|
});
|
|
74
|
-
it("should call sshExec with cmd, timeout and call back function", ()=>{
|
|
75
|
-
const cb = ()=>{};
|
|
72
|
+
it("should call sshExec with cmd, timeout and call back function", () => {
|
|
73
|
+
const cb = () => {};
|
|
76
74
|
ssh.exec("ls", 10, cb);
|
|
77
75
|
expect(sshExec).to.be.calledWith(hostInfo, "ls", 10, cb);
|
|
78
76
|
});
|
|
79
|
-
it("should reject if cmd is not string (number)", ()=>{
|
|
77
|
+
it("should reject if cmd is not string (number)", () => {
|
|
80
78
|
return expect(ssh.exec(0)).to.be.rejectedWith("cmd must be string");
|
|
81
79
|
});
|
|
82
|
-
it("should reject if cmd is not string (null)", ()=>{
|
|
80
|
+
it("should reject if cmd is not string (null)", () => {
|
|
83
81
|
return expect(ssh.exec(null)).to.be.rejectedWith("cmd must be string");
|
|
84
82
|
});
|
|
85
|
-
it("should reject if cmd is empty string", ()=>{
|
|
83
|
+
it("should reject if cmd is empty string", () => {
|
|
86
84
|
return expect(ssh.exec("")).to.be.rejectedWith("cmd must be string");
|
|
87
85
|
});
|
|
88
86
|
});
|
|
89
|
-
describe("test for ls", ()=>{
|
|
90
|
-
it("should call ls without timeout", ()=>{
|
|
87
|
+
describe("test for ls", () => {
|
|
88
|
+
it("should call ls without timeout", () => {
|
|
91
89
|
ssh.ls("hoge");
|
|
92
90
|
expect(ls).to.be.calledWith(hostInfo, "hoge", [], 0);
|
|
93
91
|
});
|
|
94
|
-
it("should call ls with option", ()=>{
|
|
92
|
+
it("should call ls with option", () => {
|
|
95
93
|
ssh.ls("hoge", ["-l", "-r", "-t"]);
|
|
96
94
|
expect(ls).to.be.calledWith(hostInfo, "hoge", ["-l", "-r", "-t"], 0);
|
|
97
95
|
});
|
|
98
|
-
it("should call ls with option and timeout", ()=>{
|
|
96
|
+
it("should call ls with option and timeout", () => {
|
|
99
97
|
ssh.ls("hoge", ["-l", "-r", "-t"], 10);
|
|
100
98
|
expect(ls).to.be.calledWith(hostInfo, "hoge", ["-l", "-r", "-t"], 10);
|
|
101
99
|
});
|
|
102
100
|
});
|
|
103
|
-
describe("test for send", ()=>{
|
|
104
|
-
it("should call send with src and dst", ()=>{
|
|
101
|
+
describe("test for send", () => {
|
|
102
|
+
it("should call send with src and dst", () => {
|
|
105
103
|
ssh.send(["src"], "dst");
|
|
106
104
|
expect(send).to.be.calledWith(hostInfo, ["src"], "dst", [], 0);
|
|
107
105
|
});
|
|
108
|
-
it("should call send with src, dst, and opt", ()=>{
|
|
106
|
+
it("should call send with src, dst, and opt", () => {
|
|
109
107
|
ssh.send(["src"], "dst", ["--dry-run", "--delete"]);
|
|
110
108
|
expect(send).to.be.calledWith(hostInfo, ["src"], "dst", ["--dry-run", "--delete"], 0);
|
|
111
109
|
});
|
|
112
|
-
it("should call send with src, dst, opt, and timeout", ()=>{
|
|
110
|
+
it("should call send with src, dst, opt, and timeout", () => {
|
|
113
111
|
ssh.send(["src"], "dst", ["--dry-run", "--delete"], 10);
|
|
114
112
|
expect(send).to.be.calledWith(hostInfo, ["src"], "dst", ["--dry-run", "--delete"], 10);
|
|
115
113
|
});
|
|
116
|
-
it("should be rejected if src is not array of string", ()=>{
|
|
114
|
+
it("should be rejected if src is not array of string", () => {
|
|
117
115
|
return expect(ssh.send(1)).to.be.rejectedWith("src must be array of string");
|
|
118
116
|
});
|
|
119
|
-
it("should be rejected if src has only empty string element", ()=>{
|
|
117
|
+
it("should be rejected if src has only empty string element", () => {
|
|
120
118
|
return expect(ssh.send(["", ""])).to.be.rejectedWith("src must contain non-empty string");
|
|
121
119
|
});
|
|
122
|
-
it("should be rejected if src has only empty string element", ()=>{
|
|
120
|
+
it("should be rejected if src has only empty string element", () => {
|
|
123
121
|
return expect(ssh.send([""])).to.be.rejectedWith("src must contain non-empty string");
|
|
124
122
|
});
|
|
125
|
-
it("should be called if src includes empty string ", ()=>{
|
|
123
|
+
it("should be called if src includes empty string ", () => {
|
|
126
124
|
ssh.send(["src", ""], "dst");
|
|
127
125
|
expect(send).to.be.calledWith(hostInfo, ["src", ""], "dst", [], 0);
|
|
128
126
|
});
|
|
129
|
-
it("should be rejected if dst is not string", ()=>{
|
|
127
|
+
it("should be rejected if dst is not string", () => {
|
|
130
128
|
return expect(ssh.send(["src"], 0)).to.be.rejectedWith("dst must be string");
|
|
131
129
|
});
|
|
132
|
-
it("should be rejected if dst is empty string", ()=>{
|
|
130
|
+
it("should be rejected if dst is empty string", () => {
|
|
133
131
|
return expect(ssh.send(["src"], "")).to.be.rejectedWith("dst must be non-empty string");
|
|
134
132
|
});
|
|
135
|
-
it("should be rejected if opt is not array of string", ()=>{
|
|
133
|
+
it("should be rejected if opt is not array of string", () => {
|
|
136
134
|
return expect(ssh.send(["src"], "dst", [null])).to.be.rejectedWith("opt must be array of string");
|
|
137
135
|
});
|
|
138
136
|
});
|
|
139
|
-
describe("test for recv", ()=>{
|
|
140
|
-
it("should call recv with src and dst", ()=>{
|
|
137
|
+
describe("test for recv", () => {
|
|
138
|
+
it("should call recv with src and dst", () => {
|
|
141
139
|
ssh.recv(["src"], "dst");
|
|
142
140
|
expect(recv).to.be.calledWith(hostInfo, ["src"], "dst", [], 0);
|
|
143
141
|
});
|
|
144
|
-
it("should call recv with src, dst, and opt", ()=>{
|
|
142
|
+
it("should call recv with src, dst, and opt", () => {
|
|
145
143
|
ssh.recv(["src"], "dst", ["--dry-run", "--delete"]);
|
|
146
144
|
expect(recv).to.be.calledWith(hostInfo, ["src"], "dst", ["--dry-run", "--delete"], 0);
|
|
147
145
|
});
|
|
148
|
-
it("should call recv with src, dst, opt, and timeout", ()=>{
|
|
146
|
+
it("should call recv with src, dst, opt, and timeout", () => {
|
|
149
147
|
ssh.recv(["src"], "dst", ["--dry-run", "--delete"], 10);
|
|
150
148
|
expect(recv).to.be.calledWith(hostInfo, ["src"], "dst", ["--dry-run", "--delete"], 10);
|
|
151
149
|
});
|
|
152
|
-
it("should be rejected if src is not array of string", ()=>{
|
|
150
|
+
it("should be rejected if src is not array of string", () => {
|
|
153
151
|
return expect(ssh.recv(1)).to.be.rejectedWith("src must be array of string");
|
|
154
152
|
});
|
|
155
|
-
it("should be rejected if src has only empty string element", ()=>{
|
|
153
|
+
it("should be rejected if src has only empty string element", () => {
|
|
156
154
|
return expect(ssh.recv(["", ""])).to.be.rejectedWith("src must contain non-empty string");
|
|
157
155
|
});
|
|
158
|
-
it("should be rejected if src has only empty string element", ()=>{
|
|
156
|
+
it("should be rejected if src has only empty string element", () => {
|
|
159
157
|
return expect(ssh.recv([""])).to.be.rejectedWith("src must contain non-empty string");
|
|
160
158
|
});
|
|
161
|
-
it("should be called if src includes empty string ", ()=>{
|
|
159
|
+
it("should be called if src includes empty string ", () => {
|
|
162
160
|
ssh.recv(["src", ""], "dst");
|
|
163
161
|
expect(recv).to.be.calledWith(hostInfo, ["src", ""], "dst", [], 0);
|
|
164
162
|
});
|
|
165
|
-
it("should be rejected if dst is not string", ()=>{
|
|
163
|
+
it("should be rejected if dst is not string", () => {
|
|
166
164
|
return expect(ssh.recv(["src"], 0)).to.be.rejectedWith("dst must be string");
|
|
167
165
|
});
|
|
168
|
-
it("should be rejected if dst is empty string", ()=>{
|
|
166
|
+
it("should be rejected if dst is empty string", () => {
|
|
169
167
|
return expect(ssh.recv(["src"], "")).to.be.rejectedWith("dst must be non-empty string");
|
|
170
168
|
});
|
|
171
|
-
it("should be rejected if opt is not array of string", ()=>{
|
|
169
|
+
it("should be rejected if opt is not array of string", () => {
|
|
172
170
|
return expect(ssh.recv(["src"], "dst", [null])).to.be.rejectedWith("opt must be array of string");
|
|
173
171
|
});
|
|
174
172
|
});
|