From 95fe387c1e807bede0c309559907ae634115a424 Mon Sep 17 00:00:00 2001 From: jace-roell Date: Mon, 9 Dec 2024 16:38:45 -0500 Subject: [PATCH 1/5] apiResponse Signed-off-by: jace-roell --- .../methods/upload/Upload.unit.test.ts | 2 ++ .../zosfiles/src/methods/upload/Upload.ts | 24 +++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/packages/zosfiles/__tests__/__unit__/methods/upload/Upload.unit.test.ts b/packages/zosfiles/__tests__/__unit__/methods/upload/Upload.unit.test.ts index 28812678c8..284301aecd 100644 --- a/packages/zosfiles/__tests__/__unit__/methods/upload/Upload.unit.test.ts +++ b/packages/zosfiles/__tests__/__unit__/methods/upload/Upload.unit.test.ts @@ -392,6 +392,7 @@ describe("z/OS Files - Upload", () => { expect(error).toBeUndefined(); expect(response).toBeDefined(); + expect(response.apiResponse).toMatchObject({"from": "Buffer<>", "success": true, "to": dsName}); expect(zosmfPutFullSpy).toHaveBeenCalledTimes(1); expect(zosmfPutFullSpy).toHaveBeenCalledWith(dummySession, {resource: endpoint, @@ -1755,6 +1756,7 @@ describe("z/OS Files - Upload", () => { expect(error).toBeUndefined(); expect(USSresponse).toBeDefined(); + expect(USSresponse.apiResponse).toMatchObject({"from": "Buffer<>", "success": true, "to": dsName}); const normalizedData = ZosFilesUtils.normalizeNewline(data); expect(data.length).not.toBe(normalizedData.length); diff --git a/packages/zosfiles/src/methods/upload/Upload.ts b/packages/zosfiles/src/methods/upload/Upload.ts index 2f984ededa..527b1a3c3b 100644 --- a/packages/zosfiles/src/methods/upload/Upload.ts +++ b/packages/zosfiles/src/methods/upload/Upload.ts @@ -184,7 +184,11 @@ export class Upload { const uploadRequest: IRestClientResponse = await ZosmfRestClient.putExpectFullResponse(session, requestOptions); // By default, apiResponse is empty when uploading - const apiResponse: any = {}; + const apiResponse: any = { + success: true, + from: "Buffer<>", + to: dataSetName + }; // Return Etag in apiResponse, if requested if (options.returnEtag) { @@ -242,7 +246,11 @@ export class Upload { const uploadRequest: IRestClientResponse = await ZosmfRestClient.putExpectFullResponse(session, requestOptions); // By default, apiResponse is empty when uploading - const apiResponse: any = {}; + const apiResponse: any = { + success: true, + from: "Stream<>", + to: dataSetName + }; // Return Etag in apiResponse, if requested if (options.returnEtag) { @@ -481,7 +489,11 @@ export class Upload { const uploadRequest: IRestClientResponse = await ZosmfRestClient.putExpectFullResponse(session, requestOptions); // By default, apiResponse is empty when uploading - const apiResponse: any = {}; + const apiResponse: any = { + success: true, + from: "Buffer<>", + to: ussname + }; // Return Etag in apiResponse, if requested if (options.returnEtag) { @@ -541,7 +553,11 @@ export class Upload { } // By default, apiResponse is empty when uploading - const apiResponse: any = {}; + const apiResponse: any = { + success: true, + from: "Stream<>", + to: ussname + }; // Return Etag in apiResponse, if requested if (options.returnEtag) { From 5153819cea96b347b47a2a24ef6841d809b36ead Mon Sep 17 00:00:00 2001 From: jace-roell Date: Tue, 10 Dec 2024 09:04:29 -0500 Subject: [PATCH 2/5] modify unit tests Signed-off-by: jace-roell --- .../__tests__/__unit__/methods/upload/Upload.unit.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/zosfiles/__tests__/__unit__/methods/upload/Upload.unit.test.ts b/packages/zosfiles/__tests__/__unit__/methods/upload/Upload.unit.test.ts index 284301aecd..69420591e3 100644 --- a/packages/zosfiles/__tests__/__unit__/methods/upload/Upload.unit.test.ts +++ b/packages/zosfiles/__tests__/__unit__/methods/upload/Upload.unit.test.ts @@ -749,6 +749,7 @@ describe("z/OS Files - Upload", () => { expect(error).toBeUndefined(); expect(response).toBeDefined(); + expect(response.apiResponse).toMatchObject({"from": "Stream<>", "success": true, "to": dsName}); expect(zosmfPutFullSpy).toHaveBeenCalledTimes(1); expect(zosmfPutFullSpy).toHaveBeenCalledWith(dummySession, {resource: endpoint, @@ -1832,6 +1833,7 @@ describe("z/OS Files - Upload", () => { expect(error).toBeUndefined(); expect(USSresponse).toBeDefined(); + expect(USSresponse.apiResponse).toMatchObject({"from": "Stream<>", "success": true, "to": dsName}); expect(USSresponse.success).toBeTruthy(); expect(zosmfExpectFullSpy).toHaveBeenCalledTimes(1); From 981acaaaa3ca600ebb85401a7ad604f8dcdd2e86 Mon Sep 17 00:00:00 2001 From: jace-roell Date: Tue, 10 Dec 2024 10:30:36 -0500 Subject: [PATCH 3/5] system test implementation Signed-off-by: jace-roell --- .../methods/upload/Upload.system.test.ts | 72 ++++++++++++++++++- .../zosfiles/src/methods/upload/Upload.ts | 7 +- 2 files changed, 75 insertions(+), 4 deletions(-) diff --git a/packages/zosfiles/__tests__/__system__/methods/upload/Upload.system.test.ts b/packages/zosfiles/__tests__/__system__/methods/upload/Upload.system.test.ts index 158729d6ce..121fa142ca 100644 --- a/packages/zosfiles/__tests__/__system__/methods/upload/Upload.system.test.ts +++ b/packages/zosfiles/__tests__/__system__/methods/upload/Upload.system.test.ts @@ -19,6 +19,7 @@ import { deleteFiles, getUniqueDatasetName, stripNewLines, wait, waitTime } from import * as fs from "fs"; import { ITestEnvironment } from "../../../../../../__tests__/__src__/environment/ITestEnvironment"; import { runCliScript } from "../../../../../../__tests__/__packages__/cli-test-utils/src"; +import { Readable } from "stream"; let REAL_SESSION: Session; let testEnvironment: ITestEnvironment; @@ -309,6 +310,51 @@ describe("Upload Data Set", () => { } }); + it("should upload a PDS file - bufferToDataSet()", async () => { + let error; + let uploadResponse; + let getResponse; + const data: Buffer = Buffer.from(testdata); + dsname = dsname+("(TEST)"); + + try { + uploadResponse = await Upload.bufferToDataSet(REAL_SESSION, data, dsname); + getResponse = await Get.dataSet(REAL_SESSION, dsname); + } catch (err) { + error = err; + Imperative.console.info("Error: " + inspect(error)); + } + + expect(error).toBeFalsy(); + + expect(uploadResponse.apiResponse).toMatchObject({"success": true, "from": "Buffer<>","to": dsname}); + expect(Buffer.from(getResponse.toString().trim())).toEqual(data); + }); + + it("should upload a PDS file - streamToDataSet()", async () => { + let error; + let uploadResponse; + let getResponse; + + const inputStream = new Readable(); + inputStream.push(testdata); + inputStream.push(null); + dsname = dsname+("(TEST)"); + + try { + uploadResponse = await Upload.streamToDataSet(REAL_SESSION, inputStream, dsname); + getResponse = await Get.dataSet(REAL_SESSION, dsname); + } catch (err) { + error = err; + Imperative.console.info("Error: " + inspect(error)); + } + + expect(error).toBeFalsy(); + + expect(uploadResponse.apiResponse).toMatchObject({"success": true, "from": "Stream<>","to": dsname}); + expect(getResponse.toString().trim()).toEqual(testdata); + }); + it("should upload a file to a partitioned data set member using full path", async () => { let error; let response: IZosFilesResponse; @@ -733,7 +779,7 @@ describe("Upload USS file", () => { await deleteFiles(REAL_SESSION, ussname); }); - it("should upload a USS file", async () => { + it("should upload a USS file - bufferToUssFile()", async () => { let error; let uploadResponse; let getResponse; @@ -748,9 +794,33 @@ describe("Upload USS file", () => { } expect(error).toBeFalsy(); + + expect(uploadResponse.apiResponse).toMatchObject({"success": true, "from": "Buffer<>","to": ussname}); expect(getResponse).toEqual(Buffer.from(data.toString())); + }); + it("should upload a USS file - streamToUssFile()", async () => { + let error; + let uploadResponse; + let getResponse; + const inputStream = new Readable(); + inputStream.push(testdata); + inputStream.push(null); + + try { + uploadResponse = await Upload.streamToUssFile(REAL_SESSION, ussname, inputStream); + getResponse = await Get.USSFile(REAL_SESSION, ussname); + } catch (err) { + error = err; + Imperative.console.info("Error: " + inspect(error)); + } + + expect(error).toBeFalsy(); + + expect(uploadResponse.apiResponse).toMatchObject({"success": true, "from": "Stream<>","to": ussname}); + expect(getResponse).toEqual(Buffer.from(testdata)); }); + it("should upload a USS file in binary mode", async () => { let error; let uploadResponse; diff --git a/packages/zosfiles/src/methods/upload/Upload.ts b/packages/zosfiles/src/methods/upload/Upload.ts index 527b1a3c3b..7285e91633 100644 --- a/packages/zosfiles/src/methods/upload/Upload.ts +++ b/packages/zosfiles/src/methods/upload/Upload.ts @@ -489,10 +489,11 @@ export class Upload { const uploadRequest: IRestClientResponse = await ZosmfRestClient.putExpectFullResponse(session, requestOptions); // By default, apiResponse is empty when uploading - const apiResponse: any = { + const apiResponse: any = + { success: true, from: "Buffer<>", - to: ussname + to: origUssname }; // Return Etag in apiResponse, if requested @@ -556,7 +557,7 @@ export class Upload { const apiResponse: any = { success: true, from: "Stream<>", - to: ussname + to: origUssname }; // Return Etag in apiResponse, if requested From 4c650d95482c9aa8dd92a0839ba93f5d3a1af5c8 Mon Sep 17 00:00:00 2001 From: jace-roell Date: Tue, 10 Dec 2024 10:59:53 -0500 Subject: [PATCH 4/5] changelog and fix system tests Signed-off-by: jace-roell --- packages/zosfiles/CHANGELOG.md | 1 + .../methods/upload/Upload.system.test.ts | 14 ++++++-------- packages/zosfiles/src/methods/upload/Upload.ts | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/zosfiles/CHANGELOG.md b/packages/zosfiles/CHANGELOG.md index e9715b05ad..33cdb9b9b7 100644 --- a/packages/zosfiles/CHANGELOG.md +++ b/packages/zosfiles/CHANGELOG.md @@ -4,6 +4,7 @@ All notable changes to the Zowe z/OS files SDK package will be documented in thi ## Recent Changes +- BugFix: Corrected the `apiResponse` response value from `streamToDataSet()`,`streamToUss()`,`bufferToUss()` and `bufferToDataSet()` on the Upload SDK. [#2381](https://github.com/zowe/zowe-cli/pull/2381) - BugFix: Corrected the `Upload.BufferToUssFile()` SDK function to properly tag uploaded files. [#2378](https://github.com/zowe/zowe-cli/pull/2378) ## `8.9.0` diff --git a/packages/zosfiles/__tests__/__system__/methods/upload/Upload.system.test.ts b/packages/zosfiles/__tests__/__system__/methods/upload/Upload.system.test.ts index 121fa142ca..adeaa4f699 100644 --- a/packages/zosfiles/__tests__/__system__/methods/upload/Upload.system.test.ts +++ b/packages/zosfiles/__tests__/__system__/methods/upload/Upload.system.test.ts @@ -315,11 +315,10 @@ describe("Upload Data Set", () => { let uploadResponse; let getResponse; const data: Buffer = Buffer.from(testdata); - dsname = dsname+("(TEST)"); try { - uploadResponse = await Upload.bufferToDataSet(REAL_SESSION, data, dsname); - getResponse = await Get.dataSet(REAL_SESSION, dsname); + uploadResponse = await Upload.bufferToDataSet(REAL_SESSION, data, dsname+"(TEST)"); + getResponse = await Get.dataSet(REAL_SESSION, dsname+"(TEST)"); } catch (err) { error = err; Imperative.console.info("Error: " + inspect(error)); @@ -327,7 +326,7 @@ describe("Upload Data Set", () => { expect(error).toBeFalsy(); - expect(uploadResponse.apiResponse).toMatchObject({"success": true, "from": "Buffer<>","to": dsname}); + expect(uploadResponse.apiResponse).toMatchObject({"success": true, "from": "Buffer<>","to": dsname+"(TEST)"}); expect(Buffer.from(getResponse.toString().trim())).toEqual(data); }); @@ -339,11 +338,10 @@ describe("Upload Data Set", () => { const inputStream = new Readable(); inputStream.push(testdata); inputStream.push(null); - dsname = dsname+("(TEST)"); try { - uploadResponse = await Upload.streamToDataSet(REAL_SESSION, inputStream, dsname); - getResponse = await Get.dataSet(REAL_SESSION, dsname); + uploadResponse = await Upload.streamToDataSet(REAL_SESSION, inputStream, dsname+"(TEST)"); + getResponse = await Get.dataSet(REAL_SESSION, dsname+"(TEST)"); } catch (err) { error = err; Imperative.console.info("Error: " + inspect(error)); @@ -351,7 +349,7 @@ describe("Upload Data Set", () => { expect(error).toBeFalsy(); - expect(uploadResponse.apiResponse).toMatchObject({"success": true, "from": "Stream<>","to": dsname}); + expect(uploadResponse.apiResponse).toMatchObject({"success": true, "from": "Stream<>","to": dsname+"(TEST)"}); expect(getResponse.toString().trim()).toEqual(testdata); }); diff --git a/packages/zosfiles/src/methods/upload/Upload.ts b/packages/zosfiles/src/methods/upload/Upload.ts index 7285e91633..4280d80e41 100644 --- a/packages/zosfiles/src/methods/upload/Upload.ts +++ b/packages/zosfiles/src/methods/upload/Upload.ts @@ -489,7 +489,7 @@ export class Upload { const uploadRequest: IRestClientResponse = await ZosmfRestClient.putExpectFullResponse(session, requestOptions); // By default, apiResponse is empty when uploading - const apiResponse: any = + const apiResponse: any = { success: true, from: "Buffer<>", From ac0338e558b0c169c11bd9b969e64557bf136ac8 Mon Sep 17 00:00:00 2001 From: jace-roell Date: Mon, 16 Dec 2024 09:09:06 -0500 Subject: [PATCH 5/5] added buffer and stream inspect Signed-off-by: jace-roell --- .../methods/upload/Upload.unit.test.ts | 32 +++++++++++++++---- .../zosfiles/src/methods/upload/Upload.ts | 15 +++++---- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/packages/zosfiles/__tests__/__unit__/methods/upload/Upload.unit.test.ts b/packages/zosfiles/__tests__/__unit__/methods/upload/Upload.unit.test.ts index 69420591e3..c0f92eb905 100644 --- a/packages/zosfiles/__tests__/__unit__/methods/upload/Upload.unit.test.ts +++ b/packages/zosfiles/__tests__/__unit__/methods/upload/Upload.unit.test.ts @@ -22,7 +22,7 @@ import { IUploadOptions } from "../../../../src/methods/upload/doc/IUploadOption import { Upload } from "../../../../src/methods/upload/Upload"; import { List } from "../../../../src/methods/list/List"; import { Utilities } from "../../../../src/methods/utilities/Utilities"; - +import { inspect } from "util"; import { ZosFilesUtils } from "../../../../src/utils/ZosFilesUtils"; import { stripNewLines } from "../../../../../../__tests__/__src__/TestUtils"; import { Create } from "../../../../src/methods/create"; @@ -379,7 +379,7 @@ describe("z/OS Files - Upload", () => { expect(error).toBeDefined(); expect(error).toBe(testError); }); - it("should return with proper response when upload buffer to a data set", async () => { + it("should return with proper response when upload buffer to a data set - buffer less than 10 chars", async () => { const buffer: Buffer = Buffer.from("testing"); const endpoint = path.posix.join(ZosFilesConstants.RESOURCE, ZosFilesConstants.RES_DS_FILES, dsName); const reqHeaders = [ZosmfHeaders.X_IBM_TEXT, ZosmfHeaders.ACCEPT_ENCODING]; @@ -392,7 +392,27 @@ describe("z/OS Files - Upload", () => { expect(error).toBeUndefined(); expect(response).toBeDefined(); - expect(response.apiResponse).toMatchObject({"from": "Buffer<>", "success": true, "to": dsName}); + expect(response.apiResponse).toMatchObject({"from": "", "success": true, "to": dsName}); + + expect(zosmfPutFullSpy).toHaveBeenCalledTimes(1); + expect(zosmfPutFullSpy).toHaveBeenCalledWith(dummySession, {resource: endpoint, + reqHeaders, + writeData: buffer}); + }); + it("should return with proper response when upload buffer to a data set - buffer more than 10 chars", async () => { + const buffer: Buffer = Buffer.from("bufferLargerThan10Chars"); + const endpoint = path.posix.join(ZosFilesConstants.RESOURCE, ZosFilesConstants.RES_DS_FILES, dsName); + const reqHeaders = [ZosmfHeaders.X_IBM_TEXT, ZosmfHeaders.ACCEPT_ENCODING]; + + try { + response = await Upload.bufferToDataSet(dummySession, buffer, dsName); + } catch (err) { + error = err; + } + + expect(error).toBeUndefined(); + expect(response).toBeDefined(); + expect(response.apiResponse).toMatchObject({"from": "", "success": true, "to": dsName}); expect(zosmfPutFullSpy).toHaveBeenCalledTimes(1); expect(zosmfPutFullSpy).toHaveBeenCalledWith(dummySession, {resource: endpoint, @@ -749,7 +769,7 @@ describe("z/OS Files - Upload", () => { expect(error).toBeUndefined(); expect(response).toBeDefined(); - expect(response.apiResponse).toMatchObject({"from": "Stream<>", "success": true, "to": dsName}); + expect(response.apiResponse).toMatchObject({"from": "[Readable]", "success": true, "to": dsName}); expect(zosmfPutFullSpy).toHaveBeenCalledTimes(1); expect(zosmfPutFullSpy).toHaveBeenCalledWith(dummySession, {resource: endpoint, @@ -1757,7 +1777,7 @@ describe("z/OS Files - Upload", () => { expect(error).toBeUndefined(); expect(USSresponse).toBeDefined(); - expect(USSresponse.apiResponse).toMatchObject({"from": "Buffer<>", "success": true, "to": dsName}); + expect(USSresponse.apiResponse).toMatchObject({"from": "", "success": true, "to": dsName}); const normalizedData = ZosFilesUtils.normalizeNewline(data); expect(data.length).not.toBe(normalizedData.length); @@ -1833,7 +1853,7 @@ describe("z/OS Files - Upload", () => { expect(error).toBeUndefined(); expect(USSresponse).toBeDefined(); - expect(USSresponse.apiResponse).toMatchObject({"from": "Stream<>", "success": true, "to": dsName}); + expect(USSresponse.apiResponse).toMatchObject({"from": "[Readable]", "success": true, "to": dsName}); expect(USSresponse.success).toBeTruthy(); expect(zosmfExpectFullSpy).toHaveBeenCalledTimes(1); diff --git a/packages/zosfiles/src/methods/upload/Upload.ts b/packages/zosfiles/src/methods/upload/Upload.ts index 4280d80e41..9301c81bfc 100644 --- a/packages/zosfiles/src/methods/upload/Upload.ts +++ b/packages/zosfiles/src/methods/upload/Upload.ts @@ -30,7 +30,7 @@ import { Utilities, Tag } from "../utilities"; import { Readable } from "stream"; import { CLIENT_PROPERTY } from "../../doc/types/ZosmfRestClientProperties"; import { TransferMode } from "../../utils/ZosFilesAttributes"; - +import { inspect } from "util"; export class Upload { @@ -183,10 +183,11 @@ export class Upload { } const uploadRequest: IRestClientResponse = await ZosmfRestClient.putExpectFullResponse(session, requestOptions); + const maxBufferPreviewSize = 10; // By default, apiResponse is empty when uploading const apiResponse: any = { success: true, - from: "Buffer<>", + from: fileBuffer.length > maxBufferPreviewSize ? inspect(fileBuffer.subarray(0, maxBufferPreviewSize)).slice(0, -1) + "...>" : inspect(fileBuffer), to: dataSetName }; @@ -248,7 +249,7 @@ export class Upload { // By default, apiResponse is empty when uploading const apiResponse: any = { success: true, - from: "Stream<>", + from: inspect(fileStream, { showHidden: false, depth: -1}), to: dataSetName }; @@ -488,11 +489,11 @@ export class Upload { } const uploadRequest: IRestClientResponse = await ZosmfRestClient.putExpectFullResponse(session, requestOptions); + const maxBufferPreviewSize = 10; // By default, apiResponse is empty when uploading - const apiResponse: any = - { + const apiResponse: any = { success: true, - from: "Buffer<>", + from: fileBuffer.length > maxBufferPreviewSize ? inspect(fileBuffer.subarray(0, maxBufferPreviewSize)).slice(0, -1) + "...>" : inspect(fileBuffer), to: origUssname }; @@ -556,7 +557,7 @@ export class Upload { // By default, apiResponse is empty when uploading const apiResponse: any = { success: true, - from: "Stream<>", + from: inspect(uploadStream, { showHidden: false, depth: -1}), to: origUssname };