[ui, mirage] Evaluation mocks (#12471)

* Linear and Branching mock evaluations

* De-comment

* test-trigger

* Making evaluation trees dynamic

* Reinstated job relationship on eval mock

* Dasherize job prefix back to normal

* Handle bug where UUIDKey is not present on job

* Appending node to eval

* Job ID as a passed property

* Remove unused import

* Branching evals set up as generatable
This commit is contained in:
Phil Renaud
2022-04-27 12:11:24 -04:00
committed by GitHub
parent 3671ea6a8f
commit bae5bc16b0
9 changed files with 136 additions and 259 deletions

View File

@@ -7,6 +7,6 @@ import { computed } from '@ember/object';
// short: shortUUIDProperty('id') // 123456
export default function shortUUIDProperty(uuidKey) {
return computed(uuidKey, function () {
return this.get(uuidKey).split('-')[0];
return this.get(uuidKey)?.split('-')[0];
});
}

View File

@@ -6,7 +6,6 @@ import { generateDiff } from './factories/job-version';
import { generateTaskGroupFailures } from './factories/evaluation';
import { copy } from 'ember-copy';
import formatHost from 'nomad-ui/utils/format-host';
import { generateAcceptanceTestEvalMock } from './utils';
export function findLeader(schema) {
const agent = schema.agents.first();
@@ -263,19 +262,9 @@ export default function () {
});
this.get('/evaluations');
this.get(
'/evaluation/:id',
function ({ evaluations }, { params, queryParams }) {
const showRelated = queryParams.related;
if (showRelated) {
// we are dealing with a "related" request - return the mock
return generateAcceptanceTestEvalMock(params.id);
}
return evaluations.find(params.id);
}
);
this.get('/evaluation/:id', function ({ evaluations }, { params }) {
return evaluations.find(params.id);
});
this.get('/deployment/allocations/:id', function (schema, { params }) {
const job = schema.jobs.find(schema.deployments.find(params.id).jobId);

View File

@@ -31,9 +31,17 @@ const generateCountMap = (keysCount, list) => () => {
};
const generateNodesAvailable = generateCountMap(5, DATACENTERS);
const generateClassFiltered = generateCountMap(3, provide(10, faker.hacker.abbreviation));
const generateClassFiltered = generateCountMap(
3,
provide(10, faker.hacker.abbreviation)
);
const generateClassExhausted = generateClassFiltered;
const generateDimensionExhausted = generateCountMap(1, ['cpu', 'mem', 'disk', 'iops']);
const generateDimensionExhausted = generateCountMap(1, [
'cpu',
'mem',
'disk',
'iops',
]);
const generateQuotaExhausted = generateDimensionExhausted;
const generateScores = generateCountMap(1, ['binpack', 'job-anti-affinity']);
const generateConstraintFiltered = generateCountMap(2, [
@@ -59,7 +67,9 @@ export default Factory.extend({
createIndex: () => faker.random.number({ min: 10, max: 2000 }),
createTime() {
return faker.date.past(2 / 365, new Date(this.modifyTime / 1000000)) * 1000000;
return (
faker.date.past(2 / 365, new Date(this.modifyTime / 1000000)) * 1000000
);
},
waitUntil: null,
@@ -68,14 +78,22 @@ export default Factory.extend({
status: 'blocked',
afterCreate(evaluation, server) {
assignJob(evaluation, server);
const taskGroups = server.db.taskGroups.where({ jobId: evaluation.jobId });
const taskGroups = server.db.taskGroups.where({
jobId: evaluation.jobId,
});
const taskGroupNames = taskGroups.mapBy('name');
const failedTaskGroupsCount = faker.random.number({ min: 1, max: taskGroupNames.length });
const failedTaskGroupsCount = faker.random.number({
min: 1,
max: taskGroupNames.length,
});
const failedTaskGroupNames = [];
for (let i = 0; i < failedTaskGroupsCount; i++) {
failedTaskGroupNames.push(
...taskGroupNames.splice(faker.random.number(taskGroupNames.length - 1), 1)
...taskGroupNames.splice(
faker.random.number(taskGroupNames.length - 1),
1
)
);
}
@@ -103,7 +121,9 @@ function assignJob(evaluation, server) {
server.db.jobs.length
);
const job = evaluation.jobId ? server.db.jobs.find(evaluation.jobId) : pickOne(server.db.jobs);
const job = evaluation.jobId
? server.db.jobs.find(evaluation.jobId)
: pickOne(server.db.jobs);
evaluation.update({
jobId: job.id,
});
@@ -115,12 +135,18 @@ export function generateTaskGroupFailures() {
NodesEvaluated: faker.random.number({ min: 1, max: 100 }),
NodesExhausted: faker.random.number({ min: 1, max: 100 }),
NodesAvailable: faker.random.number(10) >= 7 ? generateNodesAvailable() : null,
ClassFiltered: faker.random.number(10) >= 7 ? generateClassFiltered() : null,
ConstraintFiltered: faker.random.number(10) >= 7 ? generateConstraintFiltered() : null,
ClassExhausted: faker.random.number(10) >= 7 ? generateClassExhausted() : null,
DimensionExhausted: faker.random.number(10) >= 7 ? generateDimensionExhausted() : null,
QuotaExhausted: faker.random.number(10) >= 7 ? generateQuotaExhausted() : null,
NodesAvailable:
faker.random.number(10) >= 7 ? generateNodesAvailable() : null,
ClassFiltered:
faker.random.number(10) >= 7 ? generateClassFiltered() : null,
ConstraintFiltered:
faker.random.number(10) >= 7 ? generateConstraintFiltered() : null,
ClassExhausted:
faker.random.number(10) >= 7 ? generateClassExhausted() : null,
DimensionExhausted:
faker.random.number(10) >= 7 ? generateDimensionExhausted() : null,
QuotaExhausted:
faker.random.number(10) >= 7 ? generateQuotaExhausted() : null,
Scores: faker.random.number(10) >= 7 ? generateScores() : null,
};
}

View File

@@ -288,7 +288,7 @@ export default Factory.extend({
if (!job.shallow) {
const knownEvaluationProperties = {
job,
jobId: job.id,
namespace: job.namespace,
};
server.createList(

View File

@@ -0,0 +1,3 @@
import { Model } from 'ember-cli-mirage';
export default Model.extend({});

View File

@@ -0,0 +1,5 @@
import { Model, hasMany, belongsTo } from 'ember-cli-mirage';
export default Model.extend({
relatedEvals: hasMany('evaluation-stub'),
});

View File

@@ -20,9 +20,11 @@ const allScenarios = {
...sysbatchScenarios,
};
const scenario = getScenarioQueryParameter() || getConfigValue('mirageScenario', 'emptyCluster');
const scenario =
getScenarioQueryParameter() ||
getConfigValue('mirageScenario', 'emptyCluster');
export default function(server) {
export default function (server) {
const activeScenario = allScenarios[scenario];
if (!activeScenario) {
throw new Error(
@@ -44,14 +46,74 @@ function smallCluster(server) {
server.create('feature', { name: 'Dynamic Application Sizing' });
server.createList('agent', 3, 'withConsulLink', 'withVaultLink');
server.createList('node', 5);
server.createList('job', 5, { createRecommendations: true });
server.createList('job', 1, { createRecommendations: true });
server.createList('allocFile', 5);
server.create('allocFile', 'dir', { depth: 2 });
server.createList('csi-plugin', 2);
// #region evaluations
// Branching: a single eval that relates to N-1 mutually-unrelated evals
const NUM_BRANCHING_EVALUATIONS = 3;
Array(NUM_BRANCHING_EVALUATIONS)
.fill()
.map((_, i) => {
return {
evaluation: server.create('evaluation', {
id: `branching_${i}`,
previousEval: i > 0 ? `branching_0` : '',
jobID: pickOne(server.db.jobs).id,
}),
evaluationStub: server.create('evaluation-stub', {
id: `branching_${i}`,
previousEval: i > 0 ? `branching_0` : '',
status: 'failed',
}),
};
})
.map((x, i, all) => {
x.evaluation.update({
relatedEvals:
i === 0
? all.filter((_, j) => j !== 0).map((e) => e.evaluation)
: all.filter((_, j) => j !== i).map((e) => e.evaluation),
});
return x;
});
// Linear: a long line of N related evaluations
const NUM_LINEAR_EVALUATIONS = 20;
Array(NUM_LINEAR_EVALUATIONS)
.fill()
.map((_, i) => {
return {
evaluation: server.create('evaluation', {
id: `linear_${i}`,
previousEval: i > 0 ? `linear_${i - 1}` : '',
jobID: pickOne(server.db.jobs).id,
}),
evaluationStub: server.create('evaluation-stub', {
id: `linear_${i}`,
previousEval: i > 0 ? `linear_${i - 1}` : '',
nextEval: `linear_${i + 1}`,
status: 'failed',
}),
};
})
.map((x, i, all) => {
x.evaluation.update({
relatedEvals: all.filter((_, j) => i !== j).map((e) => e.evaluation),
});
return x;
});
// #endregion evaluations
const csiAllocations = server.createList('allocation', 5);
const volumes = server.schema.csiVolumes.all().models;
csiAllocations.forEach(alloc => {
csiAllocations.forEach((alloc) => {
const volume = pickOne(volumes);
volume.writeAllocs.add(alloc);
volume.readAllocs.add(alloc);
@@ -120,7 +182,11 @@ function everyFeature(server) {
namespaceId: 'default',
createAllocations: false,
});
server.create('job', { type: 'batch', failedPlacements: true, namespaceId: 'default' });
server.create('job', {
type: 'batch',
failedPlacements: true,
namespaceId: 'default',
});
server.create('job', { type: 'system', namespaceId: 'default' });
server.create('job', 'periodic', { namespaceId: 'default' });
server.create('job', 'parameterized', { namespaceId: 'default' });
@@ -147,15 +213,17 @@ function createNamespaces(server) {
}
function createRegions(server) {
['americas', 'europe', 'asia', 'some-long-name-just-to-test'].forEach(id => {
server.create('region', { id });
});
['americas', 'europe', 'asia', 'some-long-name-just-to-test'].forEach(
(id) => {
server.create('region', { id });
}
);
}
/* eslint-disable */
function logTokens(server) {
console.log('TOKENS:');
server.db.tokens.forEach(token => {
server.db.tokens.forEach((token) => {
console.log(`
Name: ${token.name}
Secret: ${token.secretId}

View File

@@ -0,0 +1,6 @@
import ApplicationSerializer from './application';
export default ApplicationSerializer.extend({
embed: true,
include: ['relatedEvals'],
});

View File

@@ -26,6 +26,7 @@ export function arrToObj(prop, alias = '') {
}
export const generateAcceptanceTestEvalMock = (id) => {
return {
CreateIndex: 20,
CreateTime: 1647899150314738000,
@@ -267,224 +268,3 @@ export const generateAcceptanceTestEvalMock = (id) => {
Wait: 20000000000,
};
};
export const MOCK_EVALUATION = {
CreateIndex: 20,
CreateTime: 1647899150314738000,
ID: 'fede162c-26a6-c108-178b-1c140f9f5680',
JobID: 'example',
JobModifyIndex: 10,
ModifyIndex: 31,
ModifyTime: 1647899318007569000,
Namespace: 'default',
NextEval: 'fd1cd898-d655-c7e4-17f6-a1a2e98b18ef',
PreviousEval: 'd8a5c14f-120a-3d83-6305-90927356dd6c',
Priority: 50,
RelatedEvals: [
{
BlockedEval: '',
CreateIndex: 31,
CreateTime: 1647899318007563000,
DeploymentID: '',
ID: 'fd1cd898-d655-c7e4-17f6-a1a2e98b18ef',
JobID: 'example',
ModifyIndex: 44,
ModifyTime: 1647899591412413000,
Namespace: 'default',
NextEval: 'cac7dfa0-b79b-ee55-c86a-0ca89dffb9e1',
NodeID: '',
PreviousEval: 'fede162c-26a6-c108-178b-1c140f9f5680',
Priority: 50,
Status: 'failed',
StatusDescription: 'evaluation reached delivery limit (3)',
TriggeredBy: 'failed-follow-up',
Type: 'service',
WaitUntil: null,
},
{
BlockedEval: '',
CreateIndex: 10,
CreateTime: 1647899129298997000,
DeploymentID: '',
ID: 'd8a5c14f-120a-3d83-6305-90927356dd6c',
JobID: 'example',
ModifyIndex: 20,
ModifyTime: 1647899150314745000,
Namespace: 'default',
NextEval: 'fede162c-26a6-c108-178b-1c140f9f5680',
NodeID: '',
PreviousEval: '',
Priority: 50,
Status: 'failed',
StatusDescription: 'evaluation reached delivery limit (3)',
TriggeredBy: 'job-register',
Type: 'service',
WaitUntil: null,
},
{
BlockedEval: '',
CreateIndex: 44,
CreateTime: 1647899591412410000,
DeploymentID: '',
ID: 'cac7dfa0-b79b-ee55-c86a-0ca89dffb9e1',
JobID: 'example',
ModifyIndex: 53,
ModifyTime: 1647899729480596000,
Namespace: 'default',
NextEval: 'e49bf53c-da6a-c869-8317-f2089682f503',
NodeID: '',
PreviousEval: 'fd1cd898-d655-c7e4-17f6-a1a2e98b18ef',
Priority: 50,
Status: 'failed',
StatusDescription: 'evaluation reached delivery limit (3)',
TriggeredBy: 'failed-follow-up',
Type: 'service',
WaitUntil: null,
},
{
BlockedEval: '',
CreateIndex: 53,
CreateTime: 1647899729480592000,
DeploymentID: '',
ID: 'e49bf53c-da6a-c869-8317-f2089682f503',
JobID: 'example',
ModifyIndex: 64,
ModifyTime: 1647899881302731000,
Namespace: 'default',
NextEval: 'a8d29cfc-517c-2e4c-9722-b47e84152c64',
NodeID: '',
PreviousEval: 'cac7dfa0-b79b-ee55-c86a-0ca89dffb9e1',
Priority: 50,
Status: 'failed',
StatusDescription: 'evaluation reached delivery limit (3)',
TriggeredBy: 'failed-follow-up',
Type: 'service',
WaitUntil: null,
},
{
BlockedEval: '',
CreateIndex: 64,
CreateTime: 1647899881302723000,
DeploymentID: '',
ID: 'a8d29cfc-517c-2e4c-9722-b47e84152c64',
JobID: 'example',
ModifyIndex: 81,
ModifyTime: 1647900212725381000,
Namespace: 'default',
NextEval: 'b37d06e4-4eb4-b29d-3b4a-b0c7bf2528ad',
NodeID: '',
PreviousEval: 'e49bf53c-da6a-c869-8317-f2089682f503',
Priority: 50,
Status: 'failed',
StatusDescription: 'evaluation reached delivery limit (3)',
TriggeredBy: 'failed-follow-up',
Type: 'service',
WaitUntil: null,
},
{
BlockedEval: '',
CreateIndex: 81,
CreateTime: 1647900212725376000,
DeploymentID: '',
ID: 'b37d06e4-4eb4-b29d-3b4a-b0c7bf2528ad',
JobID: 'example',
ModifyIndex: 97,
ModifyTime: 1647900516944239000,
Namespace: 'default',
NextEval: 'd7c50aa5-5bf1-5119-d7e7-0d0ae5381856',
NodeID: '',
PreviousEval: 'a8d29cfc-517c-2e4c-9722-b47e84152c64',
Priority: 50,
Status: 'failed',
StatusDescription: 'evaluation reached delivery limit (3)',
TriggeredBy: 'failed-follow-up',
Type: 'service',
WaitUntil: null,
},
{
BlockedEval: '',
CreateIndex: 97,
CreateTime: 1647900516944236000,
DeploymentID: '',
ID: 'd7c50aa5-5bf1-5119-d7e7-0d0ae5381856',
JobID: 'example',
ModifyIndex: 114,
ModifyTime: 1647900825385587000,
Namespace: 'default',
NextEval: 'ea2239aa-26d6-8874-8c56-e1600585772b',
NodeID: '',
PreviousEval: 'b37d06e4-4eb4-b29d-3b4a-b0c7bf2528ad',
Priority: 50,
Status: 'failed',
StatusDescription: 'evaluation reached delivery limit (3)',
TriggeredBy: 'failed-follow-up',
Type: 'service',
WaitUntil: null,
},
{
BlockedEval: '',
CreateIndex: 114,
CreateTime: 1647900825385584000,
DeploymentID: '',
ID: 'ea2239aa-26d6-8874-8c56-e1600585772b',
JobID: 'example',
ModifyIndex: 128,
ModifyTime: 1647900979511304000,
Namespace: 'default',
NextEval: '25a2dd19-8d22-d1dd-280a-79860c9b8bdb',
NodeID: '',
PreviousEval: 'd7c50aa5-5bf1-5119-d7e7-0d0ae5381856',
Priority: 50,
Status: 'failed',
StatusDescription: 'evaluation reached delivery limit (3)',
TriggeredBy: 'failed-follow-up',
Type: 'service',
WaitUntil: null,
},
{
BlockedEval: '',
CreateIndex: 128,
CreateTime: 1647900979511301000,
DeploymentID: '',
ID: '25a2dd19-8d22-d1dd-280a-79860c9b8bdb',
JobID: 'example',
ModifyIndex: 136,
ModifyTime: 1647901211369652000,
Namespace: 'default',
NextEval: '1fded690-20ad-6afa-3b89-59e319dfce18',
NodeID: '',
PreviousEval: 'ea2239aa-26d6-8874-8c56-e1600585772b',
Priority: 50,
Status: 'failed',
StatusDescription: 'evaluation reached delivery limit (3)',
TriggeredBy: 'failed-follow-up',
Type: 'service',
WaitUntil: null,
},
{
BlockedEval: '',
CreateIndex: 136,
CreateTime: 1647901211369648000,
DeploymentID: '',
ID: '1fded690-20ad-6afa-3b89-59e319dfce18',
JobID: 'example',
ModifyIndex: 136,
ModifyTime: 1647901211369648000,
Namespace: 'default',
NextEval: '',
NodeID: '',
PreviousEval: '25a2dd19-8d22-d1dd-280a-79860c9b8bdb',
Priority: 50,
Status: 'pending',
StatusDescription: '',
TriggeredBy: 'failed-follow-up',
Type: 'service',
WaitUntil: null,
},
],
Status: 'failed',
StatusDescription: 'evaluation reached delivery limit (3)',
TriggeredBy: 'failed-follow-up',
Type: 'service',
Wait: 20000000000,
};