Skip to content

Commit

Permalink
fix(jobs): Binary spool files corrupted by newline normalization
Browse files Browse the repository at this point in the history
Signed-off-by: Timothy Johnson <[email protected]>
  • Loading branch information
t1m0thyj committed Oct 3, 2024
1 parent 57e9e72 commit 45332a9
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 17 deletions.
4 changes: 4 additions & 0 deletions packages/zosjobs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

All notable changes to the Zowe z/OS jobs SDK package will be documented in this file.

## Recent Changes

- BugFix: Fixed error in `DownloadJobs.downloadSpoolContentCommon` method causing binary spool files to be corrupted by newline normalization. [#2282](https://github.com/zowe/zowe-cli/issues/2282)

## `7.26.1`

- BugFix: Fixed error in `DownloadJobs.downloadSpoolContentCommon` method when encoding parameter is not specified. [#2173](https://github.com/zowe/zowe-cli/pull/2173)
Expand Down
33 changes: 17 additions & 16 deletions packages/zosjobs/__tests__/__unit__/DownloadJobs.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*
*/

import { AbstractSession, ImperativeError, IO } from "@zowe/imperative";
import { AbstractSession, Headers, ImperativeError, IO } from "@zowe/imperative";
import { DownloadJobs, GetJobs, IDownloadAllSpoolContentParms, IDownloadSpoolContentParms, IJobFile } from "../../src";
import { ZosmfRestClient } from "@zowe/core-for-zowe-sdk";
import { Writable } from "stream";
Expand Down Expand Up @@ -103,10 +103,7 @@ describe("DownloadJobs", () => {

describe("downloadAllSpoolContentCommon", () => {
it("should allow users to call downloadAllSpoolContentCommon with correct parameters", async () => {
let uri: string = "";
ZosmfRestClient.getStreamed = jest.fn(async (session: AbstractSession, resource: string, reqHeaders?: any[]): Promise<any> => {
uri = resource;
});
const getStreamedSpy = jest.spyOn(ZosmfRestClient, "getStreamed");
const allSpoolParms: IDownloadAllSpoolContentParms = {
jobid: fakeJobID,
jobname: fakeJobName,
Expand All @@ -120,14 +117,15 @@ describe("DownloadJobs", () => {

expect(GetJobs.getSpoolFiles).toHaveBeenCalled();
expect(IO.createDirsSyncFromFilePath).toHaveBeenCalledWith(expectedFile);
expect(uri).not.toContain("fileEncoding");
expect(getStreamedSpy).toHaveBeenCalledTimes(1);
const [_session, resource, reqHeaders, _responseStream, normalizeResponseNewLines] = getStreamedSpy.mock.calls[0];
expect(resource).not.toContain("fileEncoding");
expect(reqHeaders).toContain(Headers.TEXT_PLAIN_UTF8);
expect(normalizeResponseNewLines).toBe(true);
});

it("should allow users to call downloadAllSpoolContentCommon with correct parameters and binary mode", async () => {
let uri: string = "";
ZosmfRestClient.getStreamed = jest.fn(async (session: AbstractSession, resource: string, reqHeaders?: any[]): Promise<any> => {
uri = resource;
});
const getStreamedSpy = jest.spyOn(ZosmfRestClient, "getStreamed");
const allSpoolParms: IDownloadAllSpoolContentParms = {
jobid: fakeJobID,
jobname: fakeJobName,
Expand All @@ -142,14 +140,14 @@ describe("DownloadJobs", () => {

expect(GetJobs.getSpoolFiles).toHaveBeenCalled();
expect(IO.createDirsSyncFromFilePath).toHaveBeenCalledWith(expectedFile);
expect(uri).toContain("?mode=binary");
expect(getStreamedSpy).toHaveBeenCalledTimes(1);
const [_session, resource, _reqHeaders, _responseStream, normalizeResponseNewLines] = getStreamedSpy.mock.calls[0];
expect(resource).toContain("?mode=binary");
expect(normalizeResponseNewLines).toBe(false);
});

it("should allow users to call downloadAllSpoolContentCommon with correct parameters and record mode", async () => {
let uri: string = "";
ZosmfRestClient.getStreamed = jest.fn(async (session: AbstractSession, resource: string, reqHeaders?: any[]): Promise<any> => {
uri = resource;
});
const getStreamedSpy = jest.spyOn(ZosmfRestClient, "getStreamed");
const allSpoolParms: IDownloadAllSpoolContentParms = {
jobid: fakeJobID,
jobname: fakeJobName,
Expand All @@ -164,7 +162,10 @@ describe("DownloadJobs", () => {

expect(GetJobs.getSpoolFiles).toHaveBeenCalled();
expect(IO.createDirsSyncFromFilePath).toHaveBeenCalledWith(expectedFile);
expect(uri).toContain("?mode=record");
expect(getStreamedSpy).toHaveBeenCalledTimes(1);
const [_session, resource, _reqHeaders, _responseStream, normalizeResponseNewLines] = getStreamedSpy.mock.calls[0];
expect(resource).toContain("?mode=record");
expect(normalizeResponseNewLines).toBe(false);
});

it("should allow users to call downloadAllSpoolContentCommon with a job containing duplicate step names", async () => {
Expand Down
3 changes: 2 additions & 1 deletion packages/zosjobs/src/DownloadJobs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,9 @@ export class DownloadJobs {
}

const writeStream = parms.stream ?? IO.createWriteStream(file);
const normalizeResponseNewLines = !(parms.binary || parms.record);
await ZosmfRestClient.getStreamed(session, JobsConstants.RESOURCE + parameters, [Headers.TEXT_PLAIN_UTF8], writeStream,
true);
normalizeResponseNewLines);
}

/**
Expand Down

0 comments on commit 45332a9

Please sign in to comment.