diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index e8d769cd7c..3e95c4084d 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -2,6 +2,8 @@ All notable changes to the Zowe CLI package will be documented in this file. ## Recent Changes + +- BugFix: Improved output formatting for `zowe zos-tso start app` and `zowe zos-tso send app` commands by parsing and displaying relevant data rather than the entire JSON response. [#2347](https://github.com/zowe/zowe-cli/pull/2347) - Enhancement: Add the --ignore-not-found flag to avoid file-not-found error messages when deleting files so scripts are not interupted during automated batch processing. The flag bypasses warning prompts to confirm delete actions. [#2254](https://github.com/zowe/zowe-cli/pull/2254) ## `8.7.0` diff --git a/packages/cli/__tests__/zostso/__unit__/send/app/__snapshots__/SendASApp.handler.unit.test.ts.snap b/packages/cli/__tests__/zostso/__unit__/send/app/__snapshots__/SendASApp.handler.unit.test.ts.snap index 7f6ec7a519..ee35db820f 100644 --- a/packages/cli/__tests__/zostso/__unit__/send/app/__snapshots__/SendASApp.handler.unit.test.ts.snap +++ b/packages/cli/__tests__/zostso/__unit__/send/app/__snapshots__/SendASApp.handler.unit.test.ts.snap @@ -1,21 +1,30 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`receive TSO app handler behavior should properly receive and parse data from receive TSO response 1`] = ` -"{ - \\"version\\": \\"0100\\", - \\"reused\\": false, - \\"timeout\\": false, - \\"servletKey\\": \\"ZOWEUSER-127-aabeaaag\\", - \\"queueID\\": null, - \\"tsoData\\": [ - { - \\"VERSION\\": \\"0100\\", - \\"DATA\\": \\"HELLOW exec processing has started.\\" +" +" +`; + +exports[`receive TSO app handler behavior should properly receive and parse data from receive TSO response 2`] = `"HELLOW exec processing has started."`; + +exports[`receive TSO app handler behavior should properly receive and parse data from receive TSO response 3`] = `"UNIX message queue id = 1048608"`; + +exports[`receive TSO app handler behavior should properly receive and parse data from receive TSO response 4`] = ` +Object { + "queueID": null, + "reused": false, + "servletKey": "ZOWEUSER-127-aabeaaag", + "timeout": false, + "tsoData": Array [ + Object { + "DATA": "HELLOW exec processing has started.", + "VERSION": "0100", + }, + Object { + "DATA": "UNIX message queue id = 1048608", + "VERSION": "0100", }, - { - \\"VERSION\\": \\"0100\\", - \\"DATA\\": \\"UNIX message queue id = 1048608\\" - } - ] -}" + ], + "version": "0100", +} `; diff --git a/packages/cli/__tests__/zostso/__unit__/start/app/StartASApp.handler.unit.test.ts b/packages/cli/__tests__/zostso/__unit__/start/app/StartASApp.handler.unit.test.ts index ddfc9cdcd3..f5ef46273d 100644 --- a/packages/cli/__tests__/zostso/__unit__/start/app/StartASApp.handler.unit.test.ts +++ b/packages/cli/__tests__/zostso/__unit__/start/app/StartASApp.handler.unit.test.ts @@ -9,17 +9,6 @@ * */ -/* - * This program and the accompanying materials are made available under the terms of the - * Eclipse Public License v2.0 which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-v20.html - * - * SPDX-License-Identifier: EPL-2.0 - * - * Copyright Contributors to the Zowe Project. - * - */ - import { ZosmfRestClient } from "@zowe/core-for-zowe-sdk"; import { StartTso, AddressSpaceApps, IStartStopResponses } from "@zowe/zos-tso-for-zowe-sdk"; import * as StartASAppHandler from "../../../../../src/zostso/start/as-app/StartASApp.handler"; diff --git a/packages/cli/__tests__/zostso/__unit__/start/app/__snapshots__/StartASApp.handler.unit.test.ts.snap b/packages/cli/__tests__/zostso/__unit__/start/app/__snapshots__/StartASApp.handler.unit.test.ts.snap index ca5889138b..8c65aeb594 100644 --- a/packages/cli/__tests__/zostso/__unit__/start/app/__snapshots__/StartASApp.handler.unit.test.ts.snap +++ b/packages/cli/__tests__/zostso/__unit__/start/app/__snapshots__/StartASApp.handler.unit.test.ts.snap @@ -1,63 +1,105 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`receive TSO app handler behavior should properly start TSO address space and run an application at the created address space 1`] = ` -"{ - \\"reused\\": false, - \\"timeout\\": false, - \\"servletKey\\": \\"ZOWEUSER-123-aaaaaa\\", - \\"queueID\\": \\"983068\\", - \\"tsoData\\": [ - { - \\"VERSION\\": \\"0100\\", - \\"DATA\\": \\"HELLOW exec processing has started.\\" - }, - { - \\"VERSION\\": \\"0100\\", - \\"DATA\\": \\"UNIX message queue id = 983068\\" - }, - { - \\"VERSION\\": \\"0100\\", - \\"DATA\\": \\"Input message type = 32772\\" - }, - { - \\"VERSION\\": \\"0100\\", - \\"DATA\\": \\"Output message type = 4\\" - }, - { - \\"VERSION\\": \\"0100\\", - \\"DATA\\": \\"Reading application input from the UNIX message queue.\\" - } - ] -}" +" +Servlet Key: ZOWEUSER-123-aaaaaa" +`; + +exports[`receive TSO app handler behavior should properly start TSO address space and run an application at the created address space 2`] = ` +"Queue ID: 983068 +" +`; + +exports[`receive TSO app handler behavior should properly start TSO address space and run an application at the created address space 3`] = `"HELLOW exec processing has started."`; + +exports[`receive TSO app handler behavior should properly start TSO address space and run an application at the created address space 4`] = `"UNIX message queue id = 983068"`; + +exports[`receive TSO app handler behavior should properly start TSO address space and run an application at the created address space 5`] = `"Input message type = 32772"`; + +exports[`receive TSO app handler behavior should properly start TSO address space and run an application at the created address space 6`] = `"Output message type = 4"`; + +exports[`receive TSO app handler behavior should properly start TSO address space and run an application at the created address space 7`] = `"Reading application input from the UNIX message queue."`; + +exports[`receive TSO app handler behavior should properly start TSO address space and run an application at the created address space 8`] = ` +Object { + "queueID": "983068", + "reused": false, + "servletKey": "ZOWEUSER-123-aaaaaa", + "timeout": false, + "tsoData": Array [ + Object { + "DATA": "HELLOW exec processing has started.", + "VERSION": "0100", + }, + Object { + "DATA": "UNIX message queue id = 983068", + "VERSION": "0100", + }, + Object { + "DATA": "Input message type = 32772", + "VERSION": "0100", + }, + Object { + "DATA": "Output message type = 4", + "VERSION": "0100", + }, + Object { + "DATA": "Reading application input from the UNIX message queue.", + "VERSION": "0100", + }, + ], + "version": undefined, +} `; exports[`receive TSO app handler behavior should properly start TSO address space at an existing TSO address space 1`] = ` -"{ - \\"reused\\": false, - \\"timeout\\": false, - \\"servletKey\\": \\"ZOWEUSER-123-aaaaaa\\", - \\"queueID\\": \\"983068\\", - \\"tsoData\\": [ - { - \\"VERSION\\": \\"0100\\", - \\"DATA\\": \\"HELLOW exec processing has started.\\" - }, - { - \\"VERSION\\": \\"0100\\", - \\"DATA\\": \\"UNIX message queue id = 983068\\" - }, - { - \\"VERSION\\": \\"0100\\", - \\"DATA\\": \\"Input message type = 32772\\" - }, - { - \\"VERSION\\": \\"0100\\", - \\"DATA\\": \\"Output message type = 4\\" - }, - { - \\"VERSION\\": \\"0100\\", - \\"DATA\\": \\"Reading application input from the UNIX message queue.\\" - } - ] -}" +" +Servlet Key: ZOWEUSER-123-aaaaaa" +`; + +exports[`receive TSO app handler behavior should properly start TSO address space at an existing TSO address space 2`] = ` +"Queue ID: 983068 +" +`; + +exports[`receive TSO app handler behavior should properly start TSO address space at an existing TSO address space 3`] = `"HELLOW exec processing has started."`; + +exports[`receive TSO app handler behavior should properly start TSO address space at an existing TSO address space 4`] = `"UNIX message queue id = 983068"`; + +exports[`receive TSO app handler behavior should properly start TSO address space at an existing TSO address space 5`] = `"Input message type = 32772"`; + +exports[`receive TSO app handler behavior should properly start TSO address space at an existing TSO address space 6`] = `"Output message type = 4"`; + +exports[`receive TSO app handler behavior should properly start TSO address space at an existing TSO address space 7`] = `"Reading application input from the UNIX message queue."`; + +exports[`receive TSO app handler behavior should properly start TSO address space at an existing TSO address space 8`] = ` +Object { + "queueID": "983068", + "reused": false, + "servletKey": "ZOWEUSER-123-aaaaaa", + "timeout": false, + "tsoData": Array [ + Object { + "DATA": "HELLOW exec processing has started.", + "VERSION": "0100", + }, + Object { + "DATA": "UNIX message queue id = 983068", + "VERSION": "0100", + }, + Object { + "DATA": "Input message type = 32772", + "VERSION": "0100", + }, + Object { + "DATA": "Output message type = 4", + "VERSION": "0100", + }, + Object { + "DATA": "Reading application input from the UNIX message queue.", + "VERSION": "0100", + }, + ], + "version": undefined, +} `; diff --git a/packages/cli/src/zostso/receive/app/ReceiveASApp.handler.ts b/packages/cli/src/zostso/receive/app/ReceiveASApp.handler.ts index 03cd8e27fc..e48211be20 100644 --- a/packages/cli/src/zostso/receive/app/ReceiveASApp.handler.ts +++ b/packages/cli/src/zostso/receive/app/ReceiveASApp.handler.ts @@ -39,11 +39,7 @@ export default class Handler extends ZosTsoBaseHandler { commandParameters.response.console.log("\n"); response.tsoData.forEach((data) => { - if(typeof data === 'string') { - commandParameters.response.console.log(data); - } else if (data && data.DATA) { - commandParameters.response.console.log(data.DATA); - } + commandParameters.response.console.log(typeof data === 'string' ? data : data?.DATA ?? ""); }); commandParameters.response.data.setObj(response); } diff --git a/packages/cli/src/zostso/send/as-app/SendASApp.handler.ts b/packages/cli/src/zostso/send/as-app/SendASApp.handler.ts index cb14bf80a9..95676a8106 100644 --- a/packages/cli/src/zostso/send/as-app/SendASApp.handler.ts +++ b/packages/cli/src/zostso/send/as-app/SendASApp.handler.ts @@ -37,8 +37,10 @@ export default class Handler extends ZosTsoBaseHandler { commandParameters.response.progress.endSpinner(); - commandParameters.response.console.log( - JSON.stringify(response, null, 2) - ); + commandParameters.response.console.log("\n"); + response.tsoData.forEach((data) => { + commandParameters.response.console.log(typeof data === 'string' ? data : data?.DATA ?? ""); + }); + commandParameters.response.data.setObj(response); } } diff --git a/packages/cli/src/zostso/start/as-app/StartASApp.handler.ts b/packages/cli/src/zostso/start/as-app/StartASApp.handler.ts index a5d4f4e541..eb67fcfdce 100644 --- a/packages/cli/src/zostso/start/as-app/StartASApp.handler.ts +++ b/packages/cli/src/zostso/start/as-app/StartASApp.handler.ts @@ -9,7 +9,7 @@ * */ -import { IHandlerParameters } from "@zowe/imperative"; +import { IHandlerParameters, TextUtils } from "@zowe/imperative"; import { ZosTsoBaseHandler, AddressSpaceApps } from "@zowe/zos-tso-for-zowe-sdk"; /** @@ -32,6 +32,13 @@ export default class Handler extends ZosTsoBaseHandler { }, this.mTsoStart ); - commandParameters.response.console.log(JSON.stringify(response,null,2)); + commandParameters.response.console.log(TextUtils.chalk.yellow.bold("\n" + "Servlet Key: ") + response.servletKey); + commandParameters.response.console.log(TextUtils.chalk.yellow.bold("Queue ID: ") + response.queueID + "\n"); + + response.tsoData.forEach((data) => { + commandParameters.response.console.log(typeof data === 'string' ? data : data?.DATA ?? ""); + }); + + commandParameters.response.data.setObj(response); } } diff --git a/packages/zostso/__tests__/__system__/__scripts__/send/send_tso_app_rfj.sh b/packages/zostso/__tests__/__system__/__scripts__/send/send_tso_app_rfj.sh new file mode 100755 index 0000000000..e7309bd61a --- /dev/null +++ b/packages/zostso/__tests__/__system__/__scripts__/send/send_tso_app_rfj.sh @@ -0,0 +1,13 @@ +#!/bin/bash +account=$1 +host=$2 +port=$3 +user=$4 +password=$5 +ru=$6 +servletKey=$7 +message=$8 +appKey=$9 + +zowe zos-tso send app --ak "$appKey" --sk "$servletKey" --message "$message" --account $account --host $host --port $port --user $user --password $password --ru $ru --rfj +exit $? diff --git a/packages/zostso/__tests__/__system__/__scripts__/start/start_app_existing_as.sh b/packages/zostso/__tests__/__system__/__scripts__/start/start_app_existing_as.sh index 1203459b1a..20dd1850e6 100755 --- a/packages/zostso/__tests__/__system__/__scripts__/start/start_app_existing_as.sh +++ b/packages/zostso/__tests__/__system__/__scripts__/start/start_app_existing_as.sh @@ -8,5 +8,6 @@ ru=$6 servletKey=$7 queueID=$8 file=$9 + zowe zos-tso start app --app-key "test2" --startup "EXEC '$file'" --servlet-key $servletKey --queue-id $queueID --account $account --host $host --port $port --user $user --password $password --ru $ru exit $? diff --git a/packages/zostso/__tests__/__system__/__scripts__/start/start_app_existing_as_rfj.sh b/packages/zostso/__tests__/__system__/__scripts__/start/start_app_existing_as_rfj.sh new file mode 100755 index 0000000000..a0f16124bd --- /dev/null +++ b/packages/zostso/__tests__/__system__/__scripts__/start/start_app_existing_as_rfj.sh @@ -0,0 +1,13 @@ +#!/bin/bash +account=$1 +host=$2 +port=$3 +user=$4 +password=$5 +ru=$6 +servletKey=$7 +queueID=$8 +file=$9 + +zowe zos-tso start app --app-key "test2" --startup "EXEC '$file'" --servlet-key $servletKey --queue-id $queueID --account $account --host $host --port $port --user $user --password $password --ru $ru --rfj +exit $? diff --git a/packages/zostso/__tests__/__system__/__scripts__/start/start_app_new_as.sh b/packages/zostso/__tests__/__system__/__scripts__/start/start_app_new_as.sh index d250cc7d95..b27dbd14fd 100755 --- a/packages/zostso/__tests__/__system__/__scripts__/start/start_app_new_as.sh +++ b/packages/zostso/__tests__/__system__/__scripts__/start/start_app_new_as.sh @@ -6,5 +6,7 @@ user=$4 password=$5 ru=$6 file=$7 -zowe zos-tso start app --app-key "test2" --startup "EXEC '$file'" --account $account --host $host --port $port --user $user --password $password --ru $ru +rfj=$8 + +zowe zos-tso start app --app-key "test2" --startup "EXEC '$file'" --account $account --host $host --port $port --user $user --password $password --ru $ru --rfj $rfj exit $? diff --git a/packages/zostso/__tests__/__system__/api.TsoASApp.system.test.ts b/packages/zostso/__tests__/__system__/api.TsoASApp.system.test.ts index 199725d1a8..9ef1205dfe 100644 --- a/packages/zostso/__tests__/__system__/api.TsoASApp.system.test.ts +++ b/packages/zostso/__tests__/__system__/api.TsoASApp.system.test.ts @@ -44,7 +44,7 @@ describe("All test", () => { }); describe("Start TSO app tests", () => { - it("should create TSO address space and run an application instance at the created AS", async () => { + it("should create TSO address space and run an application instance at the created AS --rfj", async () => { let error: ImperativeError; const response = runCliScript( @@ -57,7 +57,8 @@ describe("All test", () => { defaultSystem.zosmf.user, defaultSystem.zosmf.password, defaultSystem.zosmf.rejectUnauthorized, - dsname+"(TESTAPP)" + dsname+"(TESTAPP)", + true ] ); @@ -68,11 +69,39 @@ describe("All test", () => { expect(error).toBeUndefined(); await StopTso.stop( REAL_SESSION, - JSON.parse(response.stdout.toString()).servletKey + JSON.parse(response.stdout.toString()).data.servletKey + ); + }); + it("should create TSO address space and run an application instance at the created AS --no-rfj", async () => { + let error: ImperativeError; + + const response = runCliScript( + __dirname + "/__scripts__/start/start_app_new_as.sh", + testEnvironment, + [ + ACCOUNT_NUMBER, + defaultSystem.zosmf.host, + defaultSystem.zosmf.port, + defaultSystem.zosmf.user, + defaultSystem.zosmf.password, + defaultSystem.zosmf.rejectUnauthorized, + dsname+"(TESTAPP)", + false + ] + ); + + expect(response.stdout.toString()).toBeDefined(); + expect(response.stdout.toString()).toContain( + "HELLOW exec processing has started" + ); + expect(error).toBeUndefined(); + await StopTso.stop( + REAL_SESSION, + response.stdout.toString().match(/Servlet Key:\s*([A-Za-z0-9-]+)/)[1] ); }); - it("should create TSO application instance on existing address space", async () => { + it("should create TSO application instance on existing address space --rfj", async () => { dsname = getUniqueDatasetName(`${defaultSystem.zosmf.user}.ZOSTEST`); await Create.dataSet(REAL_SESSION, CreateDataSetTypeEnum.DATA_SET_PARTITIONED, dsname); await Upload.fileToDataset(REAL_SESSION, __dirname + "/__scripts__/start/test_app.rexx", dsname, {}); @@ -90,7 +119,7 @@ describe("All test", () => { }; const response = runCliScript( - __dirname + "/__scripts__/start/start_app_existing_as.sh", + __dirname + "/__scripts__/start/start_app_existing_as_rfj.sh", testEnvironment, [ ACCOUNT_NUMBER, @@ -101,7 +130,7 @@ describe("All test", () => { defaultSystem.zosmf.rejectUnauthorized, startResponse.startResponse.zosmfTsoResponse.servletKey, startResponse.startResponse.zosmfTsoResponse.queueID, - dsname+"(TESTAPP)" + dsname+"(TESTAPP)", ] ); expect(response.stdout.toString()).toBeDefined(); @@ -115,9 +144,52 @@ describe("All test", () => { startResponse.startResponse.zosmfTsoResponse.servletKey ); }); + it("should create TSO application instance on existing address space --no-rfj", async () => { + dsname = getUniqueDatasetName(`${defaultSystem.zosmf.user}.ZOSTEST`); + await Create.dataSet(REAL_SESSION, CreateDataSetTypeEnum.DATA_SET_PARTITIONED, dsname); + await Upload.fileToDataset(REAL_SESSION, __dirname + "/__scripts__/start/test_app.rexx", dsname, {}); + + const startResponse: IIssueResponse = { + success: false, + startResponse: await StartTso.start( + REAL_SESSION, + ACCOUNT_NUMBER + ), + startReady: false, + zosmfResponse: null, + commandResponse: null, + stopResponse: null, + }; + + const response = runCliScript( + __dirname + "/__scripts__/start/start_app_existing_as.sh", + testEnvironment, + [ + ACCOUNT_NUMBER, + defaultSystem.zosmf.host, + defaultSystem.zosmf.port, + defaultSystem.zosmf.user, + defaultSystem.zosmf.password, + defaultSystem.zosmf.rejectUnauthorized, + startResponse.startResponse.zosmfTsoResponse.servletKey, + startResponse.startResponse.zosmfTsoResponse.queueID, + dsname+"(TESTAPP)", + ] + ); + expect(response.stdout.toString()).toBeDefined(); + expect(response.stdout.toString()).toContain( + "HELLOW exec processing has started" + ); + + //Clean up test + await StopTso.stop( + REAL_SESSION, + response.stdout.toString().match(/Servlet Key:\s*([A-Za-z0-9-]+)/)[1] + ); + }); }); describe("Send TSO app tests", () => { - it("Should send message to TSO address space app", async () => { + it("Should send message to TSO address space app --no-rfj", async () => { const startResponse = runCliScript( __dirname + "/__scripts__/start/start_app_new_as.sh", testEnvironment, @@ -128,13 +200,12 @@ describe("All test", () => { defaultSystem.zosmf.user, defaultSystem.zosmf.password, defaultSystem.zosmf.rejectUnauthorized, - dsname+"(TESTAPP)" + dsname+"(TESTAPP)", + true ] ); - const startServletkey = JSON.parse( - startResponse.stdout.toString() - ).servletKey; + const startServletkey = JSON.parse(startResponse.stdout.toString()).data.servletKey; const response = runCliScript( __dirname + "/__scripts__/send/send_tso_app.sh", @@ -173,7 +244,66 @@ describe("All test", () => { expect(responses).toContain( "Application input = LONG 100" ); - expect(responses).toContain("servletKey"); + expect(responses).toContain("READY "); + + //Clean up test + await StopTso.stop(REAL_SESSION, startServletkey); + }); + it("Should send message to TSO address space app --rfj", async () => { + const startResponse = runCliScript( + __dirname + "/__scripts__/start/start_app_new_as.sh", + testEnvironment, + [ + ACCOUNT_NUMBER, + defaultSystem.zosmf.host, + defaultSystem.zosmf.port, + defaultSystem.zosmf.user, + defaultSystem.zosmf.password, + defaultSystem.zosmf.rejectUnauthorized, + dsname+"(TESTAPP)", + true + ] + ); + + const startServletkey = JSON.parse(startResponse.stdout.toString()).data.servletKey; + + const response = runCliScript( + __dirname + "/__scripts__/send/send_tso_app_rfj.sh", + testEnvironment, + [ + ACCOUNT_NUMBER, + defaultSystem.zosmf.host, + defaultSystem.zosmf.port, + defaultSystem.zosmf.user, + defaultSystem.zosmf.password, + defaultSystem.zosmf.rejectUnauthorized, + startServletkey, + "LONG 100", + "test2", + ] + ); + const response2 = runCliScript( + __dirname + "/__scripts__/receive/receive_tso_app.sh", + testEnvironment, + [ + ACCOUNT_NUMBER, + defaultSystem.zosmf.host, + defaultSystem.zosmf.port, + defaultSystem.zosmf.user, + defaultSystem.zosmf.password, + defaultSystem.zosmf.rejectUnauthorized, + startServletkey, + "test2", + "true", + ] + ); + const responses = response.stdout.toString() + response2.stdout.toString(); + + expect(response.stdout.toString()).toBeDefined(); + expect(response2.stdout.toString()).toBeDefined(); + expect(responses).toContain( + "Application input = LONG 100" + ); expect(responses).toContain("READY "); //Clean up test @@ -192,12 +322,11 @@ describe("All test", () => { defaultSystem.zosmf.user, defaultSystem.zosmf.password, defaultSystem.zosmf.rejectUnauthorized, - dsname+"(TESTAPP)" + dsname+"(TESTAPP)", + true ] ); - const startServletkey = JSON.parse( - startResponse.stdout.toString() - ).servletKey; + const startServletkey = JSON.parse(startResponse.stdout.toString()).data.servletKey; runCliScript( __dirname + "/__scripts__/send/send_tso_app.sh", testEnvironment, @@ -245,12 +374,11 @@ describe("All test", () => { defaultSystem.zosmf.user, defaultSystem.zosmf.password, defaultSystem.zosmf.rejectUnauthorized, - dsname+"(TESTAPP)" + dsname+"(TESTAPP)", + true ] ); - const startServletkey = JSON.parse( - startResponse.stdout.toString() - ).servletKey; + const startServletkey = JSON.parse(startResponse.stdout.toString()).data.servletKey; runCliScript( __dirname + "/__scripts__/send/send_tso_app.sh", testEnvironment,