ssh-client-wrapper 2.11.0 → 2.13.0

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/test/sshExec.js CHANGED
@@ -1,37 +1,41 @@
1
- "use strict";
2
- const path = require("path");
1
+ import path from "path";
2
+ import { fileURLToPath } from "url";
3
3
 
4
- process.on("unhandledRejection", console.dir); // eslint-disable-line no-console
4
+ process.on("unhandledRejection", console.dir);
5
5
  Error.traceLimit = 100000;
6
6
 
7
- // setup test framework
8
- const chai = require("chai");
9
- const { expect } = require("chai");
10
- const sinon = require("sinon");
11
- chai.use(require("sinon-chai"));
12
- chai.use(require("chai-as-promised"));
7
+ //setup test framework
8
+ import * as chai from "chai";
9
+ import { expect } from "chai";
10
+ import sinon from "sinon";
11
+ import sinonChai from "sinon-chai";
12
+ import chaiAsPromised from "chai-as-promised";
13
+ chai.use(sinonChai);
14
+ chai.use(chaiAsPromised);
13
15
 
14
16
  const sshout = sinon.stub();
15
17
 
16
- // testee
17
- const { sshExec, canConnect, disconnect, ls } = require("../lib/sshExec.js");
18
+ //testee
19
+ import { sshExec, canConnect, disconnect } from "../lib/sshExec.js";
18
20
 
19
- // test helpers
20
- const hostInfo = require("./testUtil/hostInfo.js");
21
- const { clearRemoteTestFiles, clearLocalTestFiles, createRemoteFiles, nonExisting, remoteRoot, remoteEmptyDir } = require("./testUtil/testFiles.js");
22
- const { send } = require("../lib/rsyncExec.js");
21
+ //test helpers
22
+ import hostInfo from "./testUtil/hostInfo.js";
23
+ import { clearRemoteTestFiles, clearLocalTestFiles, nonExisting } from "./testUtil/testFiles.js";
24
+ import { send } from "../lib/rsyncExec.js";
25
+
26
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
23
27
 
24
28
  describe("test for ssh execution", function () {
25
29
  const rcfilePath = "/home/testuser/testrc";
26
- this.timeout(65000);// eslint-disable-line no-invalid-this
27
- beforeEach(async () => {
30
+ this.timeout(65000);
31
+ beforeEach(async ()=>{
28
32
  sshout.reset();
29
33
  await clearRemoteTestFiles(hostInfo);
30
34
  });
31
- before(async () => {
35
+ before(async ()=>{
32
36
  await send(hostInfo, [path.resolve(__dirname, "./testUtil/testrc")], rcfilePath, [], 0);
33
37
  });
34
- after(async () => {
38
+ after(async ()=>{
35
39
  if (!process.env.TEST_KEEP_FILES) {
36
40
  await clearRemoteTestFiles(hostInfo);
37
41
  await clearLocalTestFiles();
@@ -39,28 +43,28 @@ describe("test for ssh execution", function () {
39
43
  }
40
44
  await disconnect(hostInfo);
41
45
  });
42
- describe("#exec", () => {
46
+ describe("#exec", ()=>{
43
47
  const testText = "hoge";
44
- it("should execute single command with stdout", async () => {
48
+ it("should execute single command with stdout", async ()=>{
45
49
  const rt = await sshExec(hostInfo, `echo ${testText}`, 0, sshout);
46
50
  expect(rt).to.equal(0);
47
51
  expect(sshout).to.be.called;
48
52
 
49
53
  expect(sshout).to.be.calledWithMatch(/^hoge/);
50
54
  });
51
- it("should execute single command with stderr", async () => {
55
+ it("should execute single command with stderr", async ()=>{
52
56
  const rt = await sshExec(hostInfo, `echo ${testText} >&2`, 0, sshout);
53
57
  expect(rt).to.equal(0);
54
58
  expect(sshout).to.be.called;
55
59
  expect(sshout).to.be.calledWithMatch(/^hoge/);
56
60
  });
57
- it("should execute 2 command by prependCmd ", async () => {
61
+ it("should execute 2 command by prependCmd ", async ()=>{
58
62
  const rt = await sshExec(hostInfo, `echo ${testText}`, 0, sshout, null, "echo foo");
59
63
  expect(rt).to.equal(0);
60
64
  expect(sshout).to.be.calledOnce;
61
65
  expect(sshout).to.be.calledWithMatch(/^foo\nhoge\n/);
62
66
  });
63
- it("should execute 2 command by hostInfo.prependCmd ", async () => {
67
+ it("should execute 2 command by hostInfo.prependCmd ", async ()=>{
64
68
  hostInfo.prependCmd = "echo foo";
65
69
  const rt = await sshExec(hostInfo, `echo ${testText}`, 0, sshout, null);
66
70
  expect(rt).to.equal(0);
@@ -68,13 +72,13 @@ describe("test for ssh execution", function () {
68
72
  expect(sshout).to.be.calledWithMatch(/^foo\nhoge\n/);
69
73
  delete hostInfo.prependCmd;
70
74
  });
71
- it("should execute 2 command by rcfile", async () => {
75
+ it("should execute 2 command by rcfile", async ()=>{
72
76
  const rt = await sshExec(hostInfo, `echo ${testText}`, 0, sshout, rcfilePath);
73
77
  expect(rt).to.equal(0);
74
78
  expect(sshout).to.be.calledOnce;
75
79
  expect(sshout).to.be.calledWithMatch(/^this is test rcfile\nhoge\n/);
76
80
  });
77
- it("should execute 2 command by hostInfo.prependCmd ", async () => {
81
+ it("should execute 2 command by hostInfo.prependCmd ", async ()=>{
78
82
  hostInfo.rcfile = rcfilePath;
79
83
  const rt = await sshExec(hostInfo, `echo ${testText}`, 0, sshout, null);
80
84
  expect(rt).to.equal(0);
@@ -82,92 +86,60 @@ describe("test for ssh execution", function () {
82
86
  expect(sshout).to.be.calledWithMatch(/^this is test rcfile\nhoge\n/);
83
87
  delete hostInfo.rcfile;
84
88
  });
85
- // please note that exec() resolves with non-zero value
86
- // (126 permission deny or 127 file not found)
87
- // but does not reject in following 2 cases
88
- it("should not execute command which do not have exec permission", async () => {
89
+ //please note that exec() resolves with non-zero value
90
+ //(126 permission deny or 127 file not found)
91
+ //but does not reject in following 2 cases
92
+ it("should not execute command which do not have exec permission", async ()=>{
89
93
  await sshExec(hostInfo, "echo echo hoge >hoge");
90
94
  await sshExec(hostInfo, "chmod ugo-x hoge");
91
95
  const rt = await sshExec(hostInfo, "./hoge");
92
96
  expect(rt).to.equal(126);
93
97
  });
94
- it("should resolve with 127 if command is not found", async () => {
98
+ it("should resolve with 127 if command is not found", async ()=>{
95
99
  const rt = await sshExec(hostInfo, `./${nonExisting}`);
96
100
  expect(rt).to.equal(127);
97
101
  });
98
- it("should be rejected if timeout expired", async () => {
102
+ it("should be rejected if timeout expired", async ()=>{
99
103
  return expect(sshExec(hostInfo, "sleep 60", 1)).to.be.rejectedWith("watchdog timer expired");
100
104
  });
101
105
  });
102
- describe("#canConnect", () => {
106
+ describe("#canConnect", ()=>{
103
107
  let hostInfo2;
104
- beforeEach(async () => {
108
+ beforeEach(async ()=>{
105
109
  await disconnect(hostInfo);
106
110
  hostInfo2 = { ...hostInfo };
107
111
  hostInfo2.masterPty = null;
108
112
  });
109
- afterEach(async () => {
113
+ afterEach(async ()=>{
110
114
  await disconnect(hostInfo2);
111
115
  });
112
- it("should be resolved with true", async () => {
116
+ it("should be resolved with true", async ()=>{
113
117
  return expect(await canConnect(hostInfo2, 5)).to.be.true;
114
118
  });
115
- it("should be rejected if user does not exist", async () => {
119
+ it("should be rejected if user does not exist", async ()=>{
116
120
  hostInfo2.user = "xxxx";
117
121
  return expect(canConnect(hostInfo2, 2)).to.be.rejected;
118
122
  });
119
- it("should be rejected if password is wrong", async () => {
123
+ it("should be rejected if password is wrong", async ()=>{
120
124
  hostInfo2.password = "xxxx";
121
125
  return expect(canConnect(hostInfo2, 2)).to.be.rejected;
122
126
  });
123
- it("should be rejected if host does not exist", async () => {
127
+ it("should be rejected if host does not exist", async ()=>{
124
128
  hostInfo2.host = "foo.bar.example.com";
125
129
  return expect(canConnect(hostInfo2, 2)).to.be.rejectedWith(255);
126
130
  });
127
- it("should be rejected if host(ip address) does not exist", async () => {
131
+ it("should be rejected if host(ip address) does not exist", async ()=>{
128
132
  hostInfo2.host = "192.0.2.1";
129
- hostInfo2.ConnectTimeout = 8; // please note each test will be timed out in 20 seconds
133
+ hostInfo2.ConnectTimeout = 8; //please note each test will be timed out in 20 seconds
130
134
  return expect(canConnect(hostInfo2, 2)).to.be.rejectedWith(255);
131
135
  });
132
- it("should be rejected if port number is out of range(-1)", async () => {
136
+ it("should be rejected if port number is out of range(-1)", async ()=>{
133
137
  hostInfo2.port = -1;
134
138
  return expect(canConnect(hostInfo2, 2)).to.be.rejectedWith("invalid port specified -1");
135
139
  });
136
- it("should be rejected if port number is out of range(65536)", async () => {
140
+ it("should be rejected if port number is out of range(65536)", async ()=>{
137
141
  hostInfo2.port = 65536;
138
142
  return expect(canConnect(hostInfo2, 2)).to.be.rejectedWith("invalid port specified 65536");
139
143
  });
140
144
  });
141
- describe("#ls", () => {
142
- beforeEach(async () => {
143
- await createRemoteFiles(hostInfo);
144
- });
145
- it("should return array of file and directory names in the specified directory", async () => {
146
- expect(await ls(hostInfo, remoteRoot, [], 0)).to.have.members(["foo", "bar", "baz", "hoge", "huga"]);
147
- });
148
- it("should return array which has only specified file", async () => {
149
- expect(await ls(hostInfo, path.posix.join(remoteRoot, "foo"), [], 0)).to.eql([path.posix.join(remoteRoot, "foo")]);
150
- });
151
- it("should return 'No such file or directory' if non-existing path is specified", async () => {
152
- expect(await ls(hostInfo, path.posix.join(remoteRoot, nonExisting), [], 0)).to.match(/No such file or directory/);
153
- });
154
- it("should return only matched filenames, if glob is specified", async () => {
155
- expect(await ls(hostInfo, path.posix.join(remoteRoot, "b*"), [], 0)).to.have.members(["bar", "baz"].map((e) => {
156
- return path.posix.join(remoteRoot, e);
157
- }));
158
- });
159
- it("should return only matched filenames src contains multipl glob pattern", async () => {
160
- expect(await ls(hostInfo, path.posix.join(remoteRoot, "h*", "p[iu]yo"), [], 0)).to.have.members(["piyo", "puyo"].map((e) => {
161
- return path.posix.join(remoteRoot, "hoge", e);
162
- }));
163
- });
164
- it("should return only matched filenames, if specified glob contains /", async () => {
165
- expect(await ls(hostInfo, path.posix.join(remoteRoot, "hoge/*yo"), [], 0)).to.have.members(["piyo", "puyo", "poyo"].map((e) => {
166
- return path.posix.join(remoteRoot, "hoge", e);
167
- }));
168
- });
169
- it("should return empty array if specified target is empty directory", async () => {
170
- expect(await ls(hostInfo, remoteEmptyDir, [], 0)).to.be.an("array").that.is.empty;
171
- });
172
- });
173
145
  });
@@ -1,5 +1,4 @@
1
- "use strict";
2
- module.exports = {
1
+ export default {
3
2
  host: process.env.TEST_HOST || "localhost",
4
3
  user: process.env.TEST_USER || null,
5
4
  port: process.env.TEST_PORT || 22,
@@ -1,8 +1,7 @@
1
- "use strict";
2
- const fs = require("fs-extra");
3
- const path = require("path");
1
+ import fs from "fs-extra";
2
+ import path from "path";
4
3
 
5
- const { sshExec } = require("../../lib/sshExec.js");
4
+ import { sshExec } from "../../lib/sshExec.js";
6
5
 
7
6
  /*
8
7
  * test directory tree
@@ -47,44 +46,56 @@ const nonExisting = "ARSSH_nonExisting";
47
46
  /*
48
47
  * prepare local files which contain its filename
49
48
  */
50
- async function createLocalFiles () {
49
+ /**
50
+ *
51
+ */
52
+ export async function createLocalFiles() {
51
53
  const localDir2 = path.join(localRoot, "hoge");
52
54
  const promises = [];
53
55
  await fs.mkdir(localRoot);
54
56
  await fs.mkdir(localDir2);
55
57
  promises.push(fs.mkdir(localEmptyDir));
56
- localFiles.forEach((localFile) => {
58
+ localFiles.forEach((localFile)=>{
57
59
  promises.push(fs.writeFile(localFile, `${localFile}\n`));
58
60
  });
59
61
  return Promise.all(promises);
60
62
  }
61
63
 
62
- async function clearLocalTestFiles () {
64
+ /**
65
+ *
66
+ */
67
+ export async function clearLocalTestFiles() {
63
68
  return fs.remove(localRoot);
64
69
  }
65
70
 
66
- async function createRemoteFiles (hostInfo) {
67
- // create remote files
71
+ /**
72
+ *
73
+ * @param hostInfo
74
+ */
75
+ export async function createRemoteFiles(hostInfo) {
76
+ //create remote files
68
77
  await sshExec(hostInfo, `mkdir -p ${remoteRoot}/hoge`);
69
78
  await sshExec(hostInfo, `mkdir -p ${remoteEmptyDir}`);
70
- const script = remoteFiles.reduce((a, remoteFile) => {
79
+ const script = remoteFiles.reduce((a, remoteFile)=>{
71
80
  return `${a}echo ${remoteFile} > ${remoteFile};`;
72
81
  }, "");
73
82
  return sshExec(hostInfo, `${script}`);
74
83
  }
75
84
 
76
- async function clearRemoteTestFiles (hostInfo) {
85
+ /**
86
+ *
87
+ * @param hostInfo
88
+ */
89
+ export async function clearRemoteTestFiles(hostInfo) {
77
90
  return sshExec(hostInfo, `rm -fr ${remoteRoot}`);
78
91
  }
79
92
 
80
- module.exports.createLocalFiles = createLocalFiles;
81
- module.exports.createRemoteFiles = createRemoteFiles;
82
- module.exports.clearLocalTestFiles = clearLocalTestFiles;
83
- module.exports.clearRemoteTestFiles = clearRemoteTestFiles;
84
- module.exports.localRoot = localRoot;
85
- module.exports.localEmptyDir = localEmptyDir;
86
- module.exports.localFiles = localFiles;
87
- module.exports.nonExisting = nonExisting;
88
- module.exports.remoteRoot = remoteRoot;
89
- module.exports.remoteEmptyDir = remoteEmptyDir;
90
- module.exports.remoteFiles = remoteFiles;
93
+ export {
94
+ localRoot,
95
+ localEmptyDir,
96
+ localFiles,
97
+ nonExisting,
98
+ remoteRoot,
99
+ remoteEmptyDir,
100
+ remoteFiles
101
+ };
package/.eslintrc.json DELETED
@@ -1,34 +0,0 @@
1
- {
2
- "env": {
3
- "browser": true,
4
- "commonjs": true,
5
- "es2021": true
6
- },
7
- "extends": ["standard"],
8
- "overrides": [
9
- {
10
- "env": {
11
- "node": true
12
- },
13
- "files": [
14
- ".eslintrc.{js,cjs}"
15
- ],
16
- "parserOptions": {
17
- "sourceType": "script"
18
- }
19
- }
20
- ],
21
- "parserOptions": {
22
- "ecmaVersion": "latest"
23
- },
24
- "rules": {
25
- "semi": [
26
- "error",
27
- "always"
28
- ],
29
- "quotes": [
30
- "error",
31
- "double"
32
- ]
33
- }
34
- }
@@ -1,22 +0,0 @@
1
- name: publish npm package
2
- on:
3
- push:
4
- tags:
5
- - 'v*'
6
- jobs:
7
- test:
8
- uses: ./.github/workflows/run_test.yml
9
- publish-npm:
10
- needs:
11
- - test
12
- runs-on: ubuntu-latest
13
- steps:
14
- - uses: actions/checkout@v3
15
- - uses: actions/setup-node@v3
16
- with:
17
- node-version: 20
18
- registry-url: https://registry.npmjs.org/
19
- - run: npm ci
20
- - run: npm publish
21
- env:
22
- NODE_AUTH_TOKEN: ${{ secrets.npm_token }}
@@ -1,28 +0,0 @@
1
- {
2
- "env": {
3
- "node": true,
4
- "mocha": true,
5
- "es6": true
6
- },
7
- "settings": {
8
- "node": {
9
- "allowModules": [
10
- "chai",
11
- "chai-fs",
12
- "chai-as-promised",
13
- "sinon",
14
- "sinon-chai",
15
- "fs-extra",
16
- "rewire"
17
- ]
18
- }
19
- },
20
- "plugins": [
21
- "chai-expect",
22
- "chai-friendly"
23
- ],
24
- "rules": {
25
- "no-unused-expressions": 0,
26
- "chai-friendly/no-unused-expressions": 2
27
- }
28
- }