github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/ui/mirage/factories/job.js (about) 1 import { assign } from '@ember/polyfills'; 2 import { Factory, trait } from 'ember-cli-mirage'; 3 import faker from 'nomad-ui/mirage/faker'; 4 import { provide, pickOne } from '../utils'; 5 import { DATACENTERS } from '../common'; 6 7 const REF_TIME = new Date(); 8 const JOB_PREFIXES = provide(5, faker.hacker.abbreviation); 9 const JOB_TYPES = ['service', 'batch', 'system']; 10 const JOB_STATUSES = ['pending', 'running', 'dead']; 11 12 export default Factory.extend({ 13 id: i => 14 `${faker.helpers.randomize( 15 JOB_PREFIXES 16 )}-${faker.hacker.noun().dasherize()}-${i}`.toLowerCase(), 17 18 name() { 19 return this.id; 20 }, 21 22 version: 1, 23 submitTime: () => faker.date.past(2 / 365, REF_TIME) * 1000000, 24 25 // When provided, the resourceSpec will inform how many task groups to create 26 // and how much of each resource that task group reserves. 27 // 28 // One task group, 256 MiB memory and 500 MHz cpu 29 // resourceSpec: ['M: 256, C: 500'] 30 // 31 // Two task groups 32 // resourceSpec: ['M: 256, C: 500', 'M: 1024, C: 1200'] 33 resourceSpec: null, 34 35 groupsCount() { 36 return this.resourceSpec ? this.resourceSpec.length : faker.random.number({ min: 1, max: 2 }); 37 }, 38 39 region: () => 'global', 40 type: () => faker.helpers.randomize(JOB_TYPES), 41 priority: () => faker.random.number(100), 42 allAtOnce: faker.random.boolean, 43 status: () => faker.helpers.randomize(JOB_STATUSES), 44 datacenters: () => 45 faker.helpers.shuffle(DATACENTERS).slice(0, faker.random.number({ min: 1, max: 4 })), 46 47 childrenCount: () => faker.random.number({ min: 1, max: 2 }), 48 49 periodic: trait({ 50 type: 'batch', 51 periodic: true, 52 // periodic details object 53 // serializer update for bool vs details object 54 periodicDetails: () => ({ 55 Enabled: true, 56 ProhibitOverlap: true, 57 Spec: '*/5 * * * * *', 58 SpecType: 'cron', 59 TimeZone: 'UTC', 60 }), 61 }), 62 63 parameterized: trait({ 64 type: 'batch', 65 parameterized: true, 66 // parameterized details object 67 // serializer update for bool vs details object 68 parameterizedDetails: () => ({ 69 MetaOptional: null, 70 MetaRequired: null, 71 Payload: faker.random.boolean() ? 'required' : null, 72 }), 73 }), 74 75 periodicChild: trait({ 76 // Periodic children need a parent job, 77 // It is the Periodic job's responsibility to create 78 // periodicChild jobs and provide a parent job. 79 type: 'batch', 80 }), 81 82 parameterizedChild: trait({ 83 // Parameterized children need a parent job, 84 // It is the Parameterized job's responsibility to create 85 // parameterizedChild jobs and provide a parent job. 86 type: 'batch', 87 parameterized: true, 88 dispatched: true, 89 payload: window.btoa(faker.lorem.sentence()), 90 }), 91 92 createIndex: i => i, 93 modifyIndex: () => faker.random.number({ min: 10, max: 2000 }), 94 95 // Directive used to control sub-resources 96 97 // When false, no allocations are made 98 createAllocations: true, 99 100 // When true, deployments for the job will never have a 'running' status 101 noActiveDeployment: false, 102 103 // When true, deployments for the job will always have a 'running' status 104 activeDeployment: false, 105 106 // When true, the job will have no versions or deployments (and in turn no latest deployment) 107 noDeployments: false, 108 109 // When true, an evaluation with a high modify index and placement failures is created 110 failedPlacements: false, 111 112 // When true, no evaluations have failed placements 113 noFailedPlacements: false, 114 115 // When true, all task groups get the noHostVolumes trait 116 noHostVolumes: false, 117 118 // When true, allocations for this job will fail and reschedule, randomly succeeding or not 119 withRescheduling: false, 120 121 // When true, task groups will have services 122 withGroupServices: false, 123 124 // When true, dynamic application sizing recommendations will be made 125 createRecommendations: false, 126 127 // When true, only task groups and allocations are made 128 shallow: false, 129 130 afterCreate(job, server) { 131 if (!job.namespaceId) { 132 const namespace = server.db.namespaces.length ? pickOne(server.db.namespaces).id : null; 133 job.update({ 134 namespace, 135 namespaceId: namespace, 136 }); 137 } else { 138 job.update({ 139 namespace: job.namespaceId, 140 }); 141 } 142 143 const groupProps = { 144 job, 145 createAllocations: job.createAllocations, 146 withRescheduling: job.withRescheduling, 147 withServices: job.withGroupServices, 148 createRecommendations: job.createRecommendations, 149 shallow: job.shallow, 150 }; 151 152 if (job.groupTaskCount) { 153 groupProps.count = job.groupTaskCount; 154 } 155 156 let groups; 157 if (job.noHostVolumes) { 158 groups = provide(job.groupsCount, (_, idx) => 159 server.create('task-group', 'noHostVolumes', { 160 ...groupProps, 161 resourceSpec: job.resourceSpec && job.resourceSpec.length && job.resourceSpec[idx], 162 }) 163 ); 164 } else { 165 groups = provide(job.groupsCount, (_, idx) => 166 server.create('task-group', { 167 ...groupProps, 168 resourceSpec: job.resourceSpec && job.resourceSpec.length && job.resourceSpec[idx], 169 }) 170 ); 171 } 172 173 job.update({ 174 taskGroupIds: groups.mapBy('id'), 175 }); 176 177 const hasChildren = job.periodic || (job.parameterized && !job.parentId); 178 const jobSummary = server.create('job-summary', hasChildren ? 'withChildren' : 'withSummary', { 179 jobId: job.id, 180 groupNames: groups.mapBy('name'), 181 namespace: job.namespace, 182 }); 183 184 job.update({ 185 jobSummaryId: jobSummary.id, 186 }); 187 188 const jobScale = server.create('job-scale', { 189 groupNames: groups.mapBy('name'), 190 jobId: job.id, 191 namespace: job.namespace, 192 shallow: job.shallow, 193 }); 194 195 job.update({ 196 jobScaleId: jobScale.id, 197 }); 198 199 if (!job.noDeployments) { 200 Array(faker.random.number({ min: 1, max: 3 })) 201 .fill(null) 202 .map((_, index) => { 203 return server.create('job-version', { 204 job, 205 namespace: job.namespace, 206 version: index, 207 noActiveDeployment: job.noActiveDeployment, 208 activeDeployment: job.activeDeployment, 209 }); 210 }); 211 } 212 213 if (!job.shallow) { 214 const knownEvaluationProperties = { 215 job, 216 namespace: job.namespace, 217 }; 218 server.createList( 219 'evaluation', 220 faker.random.number({ min: 1, max: 5 }), 221 knownEvaluationProperties 222 ); 223 if (!job.noFailedPlacements) { 224 server.createList( 225 'evaluation', 226 faker.random.number(3), 227 'withPlacementFailures', 228 knownEvaluationProperties 229 ); 230 } 231 232 if (job.failedPlacements) { 233 server.create( 234 'evaluation', 235 'withPlacementFailures', 236 assign(knownEvaluationProperties, { 237 modifyIndex: 4000, 238 }) 239 ); 240 } 241 } 242 243 if (job.periodic) { 244 // Create periodicChild jobs 245 server.createList('job', job.childrenCount, 'periodicChild', { 246 parentId: job.id, 247 namespaceId: job.namespaceId, 248 namespace: job.namespace, 249 createAllocations: job.createAllocations, 250 shallow: job.shallow, 251 }); 252 } 253 254 if (job.parameterized && !job.parentId) { 255 // Create parameterizedChild jobs 256 server.createList('job', job.childrenCount, 'parameterizedChild', { 257 parentId: job.id, 258 namespaceId: job.namespaceId, 259 namespace: job.namespace, 260 createAllocations: job.createAllocations, 261 shallow: job.shallow, 262 }); 263 } 264 }, 265 });