Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System tests should cleanup after themselves #2216

Open
wants to merge 58 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
d993866
keeping track of resources created during tests and adding cleanup
ATorrise Aug 6, 2024
3b01d28
tests that ive been preoccupied with
ATorrise Aug 14, 2024
fb156de
fixing these was hardgit add .
ATorrise Aug 15, 2024
960777b
ensuring more tests delete jobs from mf, also fixing delete operations
ATorrise Aug 15, 2024
68a7fdd
Merge remote-tracking branch 'origin/next' into system-test-cleanup
ATorrise Aug 15, 2024
4f059e6
finished zosjobs sdk tests and starting zosfiles sdk tests
ATorrise Aug 16, 2024
81048a7
modifying upload.system.test took the longest... removing some test f…
ATorrise Aug 21, 2024
a505c0d
took awhile to see the difference in regex between v1 and v2 that i w…
ATorrise Aug 22, 2024
56f0e9a
providing more clarity in a comment about calculating previous jobid
ATorrise Aug 22, 2024
c458433
fixing cli.zos-jobs.download and its accompanying scripts
ATorrise Aug 22, 2024
e356ac8
more cli sytem tests and ammended shell scripts
ATorrise Aug 22, 2024
123c7f9
finishin clizosjobslistspoolfiles
ATorrise Aug 22, 2024
d7b2840
fixing submit with a different, less intensive cleanup approach
ATorrise Aug 22, 2024
e1f2ca2
realizing need to keep createZosmfSession for uss files..
ATorrise Aug 23, 2024
4ccaad5
finishing cliZosjobsSubmit
ATorrise Aug 23, 2024
c5995dd
fixing error in variable name across files and finishing view spool t…
ATorrise Aug 23, 2024
a0fa936
unable to modify file like others
ATorrise Aug 26, 2024
f746a0b
deletes remaining ds from mf
ATorrise Aug 26, 2024
885a28a
Merge branch 'next' into system-test-cleanup
ATorrise Aug 26, 2024
f334c76
Update cli.zos-jobs.submit.stdin.system.test.ts to remove semicolon
ATorrise Aug 26, 2024
e11726f
Update cli.zos-jobs.submit.stdin.system.test.ts removing accidental line
ATorrise Aug 26, 2024
70cb522
whoops
ATorrise Aug 26, 2024
d87f789
Merge branch 'next' into system-test-cleanup
ATorrise Aug 26, 2024
0b475ac
changelog
ATorrise Aug 27, 2024
3853c8a
linting
ATorrise Aug 27, 2024
0159d2c
Merge branch 'next' into system-test-cleanup
ATorrise Aug 28, 2024
c7de80c
no circ dependency error?
ATorrise Aug 28, 2024
54baa2d
updating changelog
ATorrise Aug 28, 2024
ebe3570
moving things around with andrew's help
ATorrise Aug 28, 2024
663340f
moving around things in testEnv and ITestEnv
ATorrise Aug 28, 2024
9d59e1a
about to make a really big change
ATorrise Aug 29, 2024
fe2c72b
restoring clitestutils cleanup()
ATorrise Aug 29, 2024
46677f7
Merge branch 'next' into system-test-cleanup
ATorrise Aug 29, 2024
21bf9aa
fixing other testEnv
ATorrise Aug 29, 2024
a9d2865
updating imports
ATorrise Aug 29, 2024
52361c2
fixing imports
ATorrise Aug 29, 2024
309be62
hopefully not breaking
ATorrise Aug 29, 2024
585bb75
accidentally left 1 thing out of if statement
ATorrise Aug 29, 2024
a83444a
whoops
ATorrise Aug 29, 2024
bc1ffa2
making a wait util method and implementing it everywhere
ATorrise Aug 29, 2024
8ccb8f4
addressing one of fernandos comments
ATorrise Aug 30, 2024
842ee6b
timeout corrections
ATorrise Aug 30, 2024
9e8f22e
removing change to a unit test
ATorrise Aug 30, 2024
1c7a5b2
changing system test to work with 'any' job name
ATorrise Aug 30, 2024
83faac9
wiping testEnvironment.resources in cleanup
ATorrise Sep 4, 2024
6c7064b
changing the way the test works but need testing mini to be active an…
ATorrise Sep 4, 2024
deb5cfa
Merge branch 'next' into system-test-cleanup
ATorrise Sep 4, 2024
cefbff1
hopefully good to merge now
ATorrise Sep 4, 2024
aaa43b8
Merge branch 'system-test-cleanup' of https://github.com/zowe/zowe-cl…
ATorrise Sep 4, 2024
201ecc1
fixin - initializing resources
ATorrise Sep 4, 2024
4a37668
addressing timothy's requests
ATorrise Sep 19, 2024
36a19ca
Merge remote-tracking branch 'origin/next' into system-test-cleanup
ATorrise Sep 19, 2024
5e40b67
Merge branch 'master' of https://github.com/zowe/zowe-cli into system…
ATorrise Sep 19, 2024
2d1c9be
fixing runCliScrip import and TestEnvironment.cleanup
ATorrise Sep 19, 2024
d89d3b1
createSession() to createZosmfSession()
ATorrise Sep 19, 2024
ae20141
createsession to createzosmfsession
ATorrise Sep 19, 2024
54e8d99
adding import back into test
ATorrise Sep 20, 2024
9de05a2
getting things deleted
ATorrise Sep 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 46 additions & 2 deletions __tests__/__packages__/cli-test-utils/src/TestUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,53 @@
*/

import * as fs from "fs";
import { spawnSync, SpawnSyncReturns, ExecFileException } from "child_process";
import { spawnSync, SpawnSyncReturns, ExecFileException, execSync } from "child_process";
import { ITestEnvironment } from "./environment/doc/response/ITestEnvironment";
import { CommandProfiles, ICommandDefinition, IHandlerParameters } from "@zowe/imperative";
import { AbstractSession, CommandProfiles, ICommandDefinition, IHandlerParameters } from "@zowe/imperative";
import { DeleteJobs, IDeleteJobParms, IJob } from "@zowe/zos-jobs-for-zowe-sdk";

/**
* Delete a uss file from the mainframe
* @param {string} filePath - The USS path to the file
*/
export function deleteFiles(filePath: string): void {
if (fs.existsSync(filePath)) {
fs.unlinkSync(filePath);
}
execSync(`zowe zos-files delete uss-file "${filePath}" -f`);
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed

}

/**
* Delete a job from the mainframe using Zowe SDKs - IJob
* @param {AbstractSession} session - z/OSMF connection info
* @param {IJob} job - the job that you want to delete
*/
export function deleteJob(session: AbstractSession, job: IJob): void {
DeleteJobs.deleteJobForJob(session, job);
}

/**
* Delete a job from the mainframe using Zowe SDKs - jobid, jobname
* @param {AbstractSession} session - z/OSMF connection info
* @param {jobName} string - jobname for job to delete
* @param {jobId} string - jobid for job to delete
*/
export function deleteJobCommon(session: AbstractSession, job: IJob): void {
const parms: IDeleteJobParms = {
jobid: job.jobid, // job ID
jobname: job.jobname, // job name
};
DeleteJobs.deleteJobCommon(session, parms);
}

/**
* Delete a dataset by name
* @param {string} datasetName - The name of the dataset
*/
export function deleteDataset(datasetName: string): void {
execSync(`zowe zos-files delete data-set "${datasetName}" -f`);
Fixed Show fixed Hide fixed
}

/**
* Execute a CLI script
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,14 @@

import * as fs from "fs";
import * as nodePath from "path";

import * as yaml from "js-yaml";
import { v4 as uuidv4 } from "uuid";
import { ImperativeError, ImperativeExpect, IO, Logger, LoggingConfigurer, TextUtils } from "@zowe/imperative";

import { AbstractSession, ImperativeError, ImperativeExpect, IO, Logger, LoggingConfigurer, ProfileInfo, Session, TextUtils } from "@zowe/imperative";
Fixed Show fixed Hide fixed
import { ISetupEnvironmentParms } from "./doc/parms/ISetupEnvironmentParms";
import { ITestEnvironment } from "./doc/response/ITestEnvironment";
import { TempTestProfiles } from "./TempTestProfiles";
import { PROJECT_ROOT_DIR, TEST_RESOURCE_DIR, TEST_RESULT_DATA_DIR, TEST_USING_WORKSPACE } from "../TestConstants";
import { runCliScript } from "../TestUtils";
import { runCliScript, deleteFiles, deleteJob, deleteDataset } from "../TestUtils";

/**
* Use the utility methods here to setup the test environment for running APIs
Expand All @@ -43,7 +41,7 @@
* @returns {Promise<ITestEnvironment>}
* @memberof TestEnvironment
*/
public static async setUp(params: ISetupEnvironmentParms): Promise<ITestEnvironment<any>> {
public static async setUp(params: ISetupEnvironmentParms, session?: AbstractSession): Promise<ITestEnvironment<any>> {
// Validate the input parameters
ImperativeExpect.toNotBeNullOrUndefined(params,
`${TestEnvironment.ERROR_TAG} createTestEnv(): No parameters supplied.`);
Expand All @@ -66,7 +64,13 @@
const result: ITestEnvironment<any> = {
workingDir: testDirectory,
systemTestProperties: systemProps,
env
env,
resources: {
files: [],
jobs: [],
datasets: [],
...(session && { session }) // Only include session if it is passed in
}
};

if (params.installPlugin) {
Expand All @@ -85,6 +89,24 @@
return result;
}

/**
* Create a session using the default z/OSMF profile (if a session has not been added to test)
* @returns {Promise<ISession>} - A promise that resolves to the created session object
* @throws Will throw an error if reading profiles or creating the session fails
* @memberof TestEnvironment
*/
public static async createSession(): Promise<AbstractSession> {
// Load connection info from default z/OSMF profile
const profInfo = new ProfileInfo("zowe");
await profInfo.readProfilesFromDisk();
const zosmfProfAttrs = profInfo.getDefaultProfile("zosmf");
ATorrise marked this conversation as resolved.
Show resolved Hide resolved
if (!zosmfProfAttrs) {
throw new Error("Default z/OSMF profile not found.");
}
const zosmfMergedArgs = profInfo.mergeArgsForProfile(zosmfProfAttrs, { getSecureVals: true });
return ProfileInfo.createSession(zosmfMergedArgs.knownArgs);
}

/**
* Clean up your test environment.
* Deletes any temporary profiles that have been created
Expand All @@ -102,6 +124,20 @@
const pluginDir = testEnvironment.workingDir + "/plugins";
require("rimraf").sync(pluginDir);
}

// Clean up resources
// Check if session exists; if not, create one
const session = testEnvironment.resources.session || await TestEnvironment.createSession();

for (const file of testEnvironment.resources.files) {
deleteFiles(file);
}
for (const job of testEnvironment.resources.jobs) {
deleteJob(session, job);
}
for (const dataset of testEnvironment.resources.datasets) {
deleteDataset(dataset);
}
ATorrise marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,21 @@
*
*/

import { AbstractSession } from "@zowe/imperative";
import { IJob } from "@zowe/zos-jobs-for-zowe-sdk";

/**
* The test environment for your test.
* @export
* @interface ITestEnvironment
*/
export interface ITestEnvironment<TestPropertiesSchema> {
resources: {
ATorrise marked this conversation as resolved.
Show resolved Hide resolved
files: string[];
jobs: IJob[];
datasets: string[];
session?: AbstractSession;
};
/**
* The working directory for your test environment. It is a unique (uuid) area where your tests can create
* their home folders (for imperative, etc.) and you can use the area as scratch for any files, etc. that
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
#!/bin/bash
# TODO - delete the job from spool

# Submit the job and ensure the RC is 0
JOBID="$(zowe jobs submit ds "$1" --wfo true --rff jobid --rft string)"
CMDRC=$?
if [ $CMDRC -gt 0 ]
then
echo $JOBID 1>&2
echo "Submit returned a non-zero return code" 1>&2
echo "Job ID: $JOBID"
if [ $CMDRC -gt 0 ]; then
echo "Job submission failed with return code $CMDRC" 1>&2
exit $CMDRC
fi

zowe jobs search job "$2" --search-string "$3"
# Ensure the job ID is valid
if [ -z "$JOBID" ]; then
echo "Job ID is empty, cannot proceed with the search." 1>&2
exit 1
fi

# Wait for a few seconds to ensure job output is available
sleep 5

# Search the job's spool files
zowe jobs search job "$JOBID" --search-string "$3"
RC=$?
if [ $RC -gt 0 ]
then
echo $STATUS 1>&2
if [ $RC -gt 0 ]; then
echo "The search spool job command returned a non-zero rc: $RC" 1>&2
exit $RC
fi

fi
33 changes: 25 additions & 8 deletions packages/zosjobs/__tests__/__system__/CancelJobs.system.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@

import { ImperativeError, Session, RestClientError } from "@zowe/imperative";
import { CancelJobs, SubmitJobs, IJob } from "../../src";
import { ITestEnvironment } from "@zowe/cli-test-utils";
import { TestEnvironment } from "../../../../__tests__/__src__/environment/TestEnvironment";
import { ITestPropertiesSchema } from "../../../../__tests__/__src__/properties/ITestPropertiesSchema";
import { JobTestsUtils } from "./JobTestsUtils";
import { ITestEnvironment, TestEnvironment } from "@zowe/cli-test-utils";

let REAL_SESSION: Session;
let sleepJCL: string;
Expand All @@ -28,23 +27,26 @@ describe("CancelJobs System tests", () => {
beforeAll(async () => {
testEnvironment = await TestEnvironment.setUp({
testName: "zos_cancel_jobs"
});
}, REAL_SESSION = await TestEnvironment.createSession());
systemProps = testEnvironment.systemTestProperties;

REAL_SESSION = TestEnvironment.createZosmfSession(testEnvironment);

const ACCOUNT = systemProps.tso.account;
const maxStepNum = 6; // Use lots of steps to make the job stay in INPUT status longer

sleepJCL = JobTestsUtils.getSleepJCL(REAL_SESSION.ISession.user, ACCOUNT, systemProps.zosjobs.jobclass, maxStepNum);
});

afterAll(async () => {
await TestEnvironment.cleanUp(testEnvironment);
});

describe("Positive tests", () => {
it("should be able to cancel a job using cancelJob (modify version 1)", async () => {
const job = await SubmitJobs.submitJclNotifyCommon(REAL_SESSION, {jcl: sleepJCL, status: "INPUT"});
expect(job.retcode).toBeNull(); // job is not complete, no CC
const response = await CancelJobs.cancelJob(REAL_SESSION, job.jobname, job.jobid, "1.0");
expect(response).toBeUndefined();
testEnvironment.resources.jobs.push(job);
}, LONG_TIMEOUT);

it("should be able to cancel a job using cancelJob (modify version 2)", async () => {
Expand All @@ -53,6 +55,7 @@ describe("CancelJobs System tests", () => {
const response = await CancelJobs.cancelJob(REAL_SESSION, job.jobname, job.jobid, "2.0");
expect(response).not.toBeUndefined();
expect(response?.status).toEqual("0"); // intermittent failure
testEnvironment.resources.jobs.push(job);
}, LONG_TIMEOUT);

it("should be able to cancel a job using cancelJob (modify version default)", async () => {
Expand All @@ -61,13 +64,15 @@ describe("CancelJobs System tests", () => {
const response = await CancelJobs.cancelJob(REAL_SESSION, job.jobname, job.jobid);
expect(response).not.toBeUndefined();
expect(response?.status).toEqual("0"); // intermittent failure
testEnvironment.resources.jobs.push(job);
}, LONG_TIMEOUT);

it("should be able to cancel a job using cancelJobForJob (modify version 1)", async () => {
const job = await SubmitJobs.submitJclNotifyCommon(REAL_SESSION, {jcl: sleepJCL, status: "INPUT"});
expect(job.retcode).toBeNull(); // job is not complete, no CC
const response = await CancelJobs.cancelJobForJob(REAL_SESSION, job, "1.0");
expect(response).toBeUndefined();
testEnvironment.resources.jobs.push(job);
}, LONG_TIMEOUT);

it("should be able to cancel a job using cancelJobForJob (modify version 2)", async () => {
Expand All @@ -76,6 +81,7 @@ describe("CancelJobs System tests", () => {
const response = await CancelJobs.cancelJobForJob(REAL_SESSION, job, "2.0");
expect(response).not.toBeUndefined();
expect(response?.status).toEqual("0"); // intermittent failure
testEnvironment.resources.jobs.push(job);
}, LONG_TIMEOUT);

it("should be able to cancel a job using cancelJobForJob (modify version default)", async () => {
Expand All @@ -84,13 +90,15 @@ describe("CancelJobs System tests", () => {
const response = await CancelJobs.cancelJobForJob(REAL_SESSION, job);
expect(response).not.toBeUndefined();
expect(response?.status).toEqual("0"); // intermittent failure
testEnvironment.resources.jobs.push(job);
}, LONG_TIMEOUT);

it("should be able to cancel a job using cancelJobCommon (job version 1)", async () => {
const job = await SubmitJobs.submitJclNotifyCommon(REAL_SESSION, {jcl: sleepJCL, status: "INPUT"});
expect(job.retcode).toBeNull(); // job is not complete, no CC
const response = await CancelJobs.cancelJobCommon(REAL_SESSION, {jobname: job.jobname, jobid: job.jobid, version: "1.0"});
expect(response).toBeUndefined();
testEnvironment.resources.jobs.push(job);
}, LONG_TIMEOUT);

it("should be able to cancel a job using cancelJobCommon (job version 2.0 - synchronous)", async () => {
Expand All @@ -99,13 +107,15 @@ describe("CancelJobs System tests", () => {
const response = await CancelJobs.cancelJobCommon(REAL_SESSION, {jobname: job.jobname, jobid: job.jobid, version: "2.0"});
expect(response).toBeDefined();
expect(response?.status).toEqual("0"); // intermittent failure
testEnvironment.resources.jobs.push(job);
}, LONG_TIMEOUT);

it("should be able to cancel a job using cancelJobCommon (job version default)", async () => {
const job = await SubmitJobs.submitJclNotifyCommon(REAL_SESSION, {jcl: sleepJCL, status: "INPUT"});
expect(job.retcode).toBeNull(); // job is not complete, no CC
const response = await CancelJobs.cancelJobCommon(REAL_SESSION, {jobname: job.jobname, jobid: job.jobid});
expect(response?.status).toEqual("0"); // intermittent failure
testEnvironment.resources.jobs.push(job);
}, LONG_TIMEOUT);

it("should be able to cancel a job using cancelJobCommon (job version 2.0 - synchronous) and return an error feedback object", async () => {
Expand All @@ -115,6 +125,7 @@ describe("CancelJobs System tests", () => {
expect(response?.status).toEqual("0");
response = await CancelJobs.cancelJobCommon(REAL_SESSION, {jobname: job.jobname, jobid: job.jobid, version: "2.0"});
expect(response?.status).toEqual("156");
testEnvironment.resources.jobs.push(job);
}, LONG_TIMEOUT);
});

Expand Down Expand Up @@ -177,24 +188,27 @@ describe("CancelJobs System tests - encoded", () => {
beforeAll(async () => {
testEnvironment = await TestEnvironment.setUp({
testName: "zos_cancel_jobs_encoded"
});
}, REAL_SESSION = await TestEnvironment.createSession());
systemProps = testEnvironment.systemTestProperties;

REAL_SESSION = TestEnvironment.createZosmfSession(testEnvironment);

const ACCOUNT = systemProps.tso.account;
const maxStepNum = 6; // Use lots of steps to make the job stay in INPUT status longer

sleepJCL = JobTestsUtils.getSleepJCL(REAL_SESSION.ISession.user, ACCOUNT, systemProps.zosjobs.jobclass, maxStepNum, true);
});

afterAll(async () => {
await TestEnvironment.cleanUp(testEnvironment);
});

describe("Positive tests", () => {
it("should be able to cancel a job using cancelJob (modify version default)", async () => {
const job = await SubmitJobs.submitJclNotifyCommon(REAL_SESSION, {jcl: sleepJCL, status: "INPUT"});
expect(job.retcode).toBeNull(); // job is not complete, no CC
const response = await CancelJobs.cancelJob(REAL_SESSION, job.jobname, job.jobid);
expect(response).not.toBeUndefined();
expect(response?.status).toEqual("0"); // intermittent failure
testEnvironment.resources.jobs.push(job);
}, LONG_TIMEOUT);

it("should be able to cancel a job using cancelJobForJob (modify version default)", async () => {
Expand All @@ -203,13 +217,15 @@ describe("CancelJobs System tests - encoded", () => {
const response = await CancelJobs.cancelJobForJob(REAL_SESSION, job);
expect(response).not.toBeUndefined();
expect(response?.status).toEqual("0"); // intermittent failure
testEnvironment.resources.jobs.push(job);
}, LONG_TIMEOUT);

it("should be able to cancel a job using cancelJobCommon (job version default)", async () => {
const job = await SubmitJobs.submitJclNotifyCommon(REAL_SESSION, {jcl: sleepJCL, status: "INPUT"});
expect(job.retcode).toBeNull(); // job is not complete, no CC
const response = await CancelJobs.cancelJobCommon(REAL_SESSION, {jobname: job.jobname, jobid: job.jobid});
expect(response?.status).toEqual("0"); // intermittent failure
testEnvironment.resources.jobs.push(job);
}, LONG_TIMEOUT);

it("should be able to cancel a job using cancelJobCommon (job version 2.0 - synchronous) and return an error feedback object", async () => {
Expand All @@ -219,6 +235,7 @@ describe("CancelJobs System tests - encoded", () => {
expect(response?.status).toEqual("0");
response = await CancelJobs.cancelJobCommon(REAL_SESSION, {jobname: job.jobname, jobid: job.jobid, version: "2.0"});
expect(response?.status).toEqual("156");
testEnvironment.resources.jobs.push(job);
}, LONG_TIMEOUT);
});
});
Loading
Loading