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

fix(3226): refactor verify method to throw an error when pod is in the unknown waiting state #199

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
32 changes: 26 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -728,18 +728,32 @@ class K8sExecutor extends Executor {

let message;
let waitingReason;
let status;

pods.find(p => {
const status = hoek.reach(p, 'status.phase').toLowerCase();
const data = pods.find(p => {
status = hoek.reach(p, 'status.phase').toLowerCase();

waitingReason = hoek.reach(p, CONTAINER_WAITING_REASON_PATH);
if (status === 'running' || status === 'succeeded') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

message value is set but will never be used

message = `Successfully created pod. Pod status is: ${status}`;

return true;
}

if (status === 'failed' || status === 'unknown') {
message = `Failed to create pod. Pod status is: ${status}`;

return true;
}

// waitingReason is undefined when pod is running or succeeded
waitingReason = hoek.reach(p, CONTAINER_WAITING_REASON_PATH);

if (waitingReason === undefined) {
message = 'Build is no longer waiting.';

return true;
}

if (
['CrashLoopBackOff', 'CreateContainerConfigError', 'CreateContainerError', 'StartError'].includes(
waitingReason
Expand All @@ -763,13 +777,19 @@ class K8sExecutor extends Executor {
return message !== undefined;
});

logger.info(`BuildId:${buildId}, status:${message}`);
logger.info(`BuildId:${buildId}, status:${status}, waitingReason:${waitingReason}, message:${message}`);

// data is not undefined when desired status or waitingReason met
// hence no error needs to be thrown
if (data !== undefined) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we want to fix this inconsistent return from the function, consider returning an obj with message and verify status and use it in worker to decide retry plus log the message

return message;
}

// when condition above not met, throw error
if (waitingReason === 'PodInitializing') {
throw new Error('Build failed to start. Pod is still intializing.');
}

return message;
throw new Error(`Build failed to start. Status: ${status}. Reason: ${waitingReason}.`);
}

/**
Expand Down
88 changes: 73 additions & 15 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1180,7 +1180,7 @@ describe('index', function () {
items: [
{
status: {
phase: 'pending'
phase: 'Running'
},
spec: {
nodeName: 'node1.my.k8s.cluster.com'
Expand Down Expand Up @@ -1217,7 +1217,7 @@ describe('index', function () {
}
};

fakeGetPodsResponse.body.items.push(pod);
fakeGetPodsResponse.body.items.unshift(pod);

const expectedMessage = 'Build failed to start. Please reach out to your cluster admin for help.';

Expand Down Expand Up @@ -1245,7 +1245,7 @@ describe('index', function () {
}
};

fakeGetPodsResponse.body.items.push(pod);
fakeGetPodsResponse.body.items.unshift(pod);

const expectedMessage = 'Build failed to start. Please reach out to your cluster admin for help.';

Expand Down Expand Up @@ -1273,7 +1273,7 @@ describe('index', function () {
}
};

fakeGetPodsResponse.body.items.push(pod);
fakeGetPodsResponse.body.items.unshift(pod);

const expectedMessage = 'Build failed to start. Please reach out to your cluster admin for help.';

Expand Down Expand Up @@ -1301,7 +1301,7 @@ describe('index', function () {
}
};

fakeGetPodsResponse.body.items.push(pod);
fakeGetPodsResponse.body.items.unshift(pod);

const expectedMessage = 'Build failed to start. Please check if your image is valid.';

Expand Down Expand Up @@ -1329,7 +1329,7 @@ describe('index', function () {
}
};

fakeGetPodsResponse.body.items.push(pod);
fakeGetPodsResponse.body.items.unshift(pod);

const expectedMessage = 'Build failed to start. Please check if your image is valid.';

Expand Down Expand Up @@ -1357,7 +1357,7 @@ describe('index', function () {
}
};

fakeGetPodsResponse.body.items.push(pod);
fakeGetPodsResponse.body.items.unshift(pod);

const expectedMessage = 'Build failed to start. Please check if your image is valid.';

Expand Down Expand Up @@ -1385,7 +1385,7 @@ describe('index', function () {
}
};

fakeGetPodsResponse.body.items.push(pod);
fakeGetPodsResponse.body.items.unshift(pod);

const expectedMessage = 'Build failed to start. Please reach out to your cluster admin for help.';

Expand All @@ -1412,7 +1412,7 @@ describe('index', function () {
}
};

fakeGetPodsResponse.body.items.push(pod);
fakeGetPodsResponse.body.items.unshift(pod);

const expectedMessage = 'Failed to create pod. Pod status is: failed';

Expand All @@ -1430,7 +1430,7 @@ describe('index', function () {
}
};

fakeGetPodsResponse.body.items.push(pod);
fakeGetPodsResponse.body.items.unshift(pod);
const expectedMessage = 'Failed to create pod. Pod status is: failed';

requestRetryMock.withArgs(getPodsConfig).resolves(fakeGetPodsResponse);
Expand All @@ -1448,7 +1448,7 @@ describe('index', function () {
{
state: {
waiting: {
reason: 'PodIntializing',
reason: 'PodInitializing',
message: 'pod is initializing'
}
}
Expand All @@ -1458,13 +1458,13 @@ describe('index', function () {
};
const expectedMessage = 'Build failed to start. Pod is still intializing.';

fakeGetPodsResponse.body.items.push(pod);
fakeGetPodsResponse.body.items.unshift(pod);
requestRetryMock.withArgs(getPodsConfig).resolves(fakeGetPodsResponse);

try {
await executor.verify(fakeVerifyConfig);
} catch (error) {
assert.equal(expectedMessage, error);
assert.equal(expectedMessage, error.message);
}
});

Expand All @@ -1488,7 +1488,7 @@ describe('index', function () {
}
};

fakeGetPodsResponse.body.items.push(pod1);
fakeGetPodsResponse.body.items.unshift(pod1);
const pod2 = {
status: {
phase: 'pending',
Expand All @@ -1508,7 +1508,7 @@ describe('index', function () {
}
};

fakeGetPodsResponse.body.items.push(pod2);
fakeGetPodsResponse.body.items.unshift(pod2);

const expectedMessage = 'Build failed to start. Please check if your image is valid.';

Expand All @@ -1522,5 +1522,63 @@ describe('index', function () {
throw new Error('should not fail');
}
});

it('no error when waitingReason is undefined', async () => {
const pod = {
status: {
phase: 'pending',
containerStatuses: [],
metadata: {
name: 'beta_15-dsvds'
}
}
};

fakeGetPodsResponse.body.items.unshift(pod);

const expectedMessage = 'Build is no longer waiting.';

requestRetryMock.withArgs(getPodsConfig).resolves(fakeGetPodsResponse);

try {
const actualMessage = await executor.verify(fakeVerifyConfig);

assert.equal(expectedMessage, actualMessage);
} catch (error) {
throw new Error('should not fail');
}
});

it('error whenever unknown waitingReason is present', async () => {
const pod = {
status: {
phase: 'pending',
containerStatuses: [
{
state: {
waiting: {
reason: 'RandomReason',
message: 'some random message'
}
}
}
],
metadata: {
name: 'beta_15-dsvds'
}
}
};

fakeGetPodsResponse.body.items[0] = pod;
requestRetryMock.withArgs(getPodsConfig).resolves(fakeGetPodsResponse);
const expectedMessage = 'Build failed to start. Status: pending. Reason: RandomReason.';

try {
await executor.verify(fakeVerifyConfig);
throw new Error('did not fail');
} catch (error) {
assert.equal(expectedMessage, error.message);
}
});
});
});