github.com/ferranbt/nomad@v0.9.3-0.20190607002617-85c449b7667c/ui/mirage/factories/allocation.js (about) 1 import Ember from 'ember'; 2 import moment from 'moment'; 3 import { Factory, faker, trait } from 'ember-cli-mirage'; 4 import { provide, pickOne } from '../utils'; 5 6 const UUIDS = provide(100, faker.random.uuid.bind(faker.random)); 7 const CLIENT_STATUSES = ['pending', 'running', 'complete', 'failed', 'lost']; 8 const DESIRED_STATUSES = ['run', 'stop', 'evict']; 9 const REF_TIME = new Date(); 10 11 export default Factory.extend({ 12 id: i => (i >= 100 ? `${UUIDS[i % 100]}-${i}` : UUIDS[i]), 13 14 jobVersion: () => faker.random.number(10), 15 16 modifyIndex: () => faker.random.number({ min: 10, max: 2000 }), 17 modifyTime: () => faker.date.past(2 / 365, REF_TIME) * 1000000, 18 19 createIndex: () => faker.random.number({ min: 10, max: 2000 }), 20 createTime() { 21 return faker.date.past(2 / 365, new Date(this.modifyTime / 1000000)) * 1000000; 22 }, 23 24 namespace: null, 25 26 clientStatus: faker.list.random(...CLIENT_STATUSES), 27 desiredStatus: faker.list.random(...DESIRED_STATUSES), 28 29 // When true, doesn't create any resources, state, or events 30 shallow: false, 31 32 withTaskWithPorts: trait({ 33 afterCreate(allocation, server) { 34 const taskGroup = server.db.taskGroups.findBy({ name: allocation.taskGroup }); 35 const resources = taskGroup.taskIds.map(id => 36 server.create( 37 'task-resource', 38 { 39 allocation, 40 name: server.db.tasks.find(id).name, 41 }, 42 'withReservedPorts' 43 ) 44 ); 45 46 allocation.update({ taskResourceIds: resources.mapBy('id') }); 47 }, 48 }), 49 50 withoutTaskWithPorts: trait({ 51 afterCreate(allocation, server) { 52 const taskGroup = server.db.taskGroups.findBy({ name: allocation.taskGroup }); 53 const resources = taskGroup.taskIds.map(id => 54 server.create( 55 'task-resource', 56 { 57 allocation, 58 name: server.db.tasks.find(id).name, 59 }, 60 'withoutReservedPorts' 61 ) 62 ); 63 64 allocation.update({ taskResourceIds: resources.mapBy('id') }); 65 }, 66 }), 67 68 rescheduleAttempts: 0, 69 rescheduleSuccess: false, 70 71 rescheduled: trait({ 72 // Create another allocation carrying the events of this as well as the reschduleSuccess state. 73 // Pass along rescheduleAttempts after decrementing. 74 // After rescheduleAttempts hits zero, a final allocation is made with no nextAllocation and 75 // a clientStatus of failed or running, depending on rescheduleSuccess 76 afterCreate(allocation, server) { 77 const attempts = allocation.rescheduleAttempts - 1; 78 const previousEvents = 79 (allocation.rescheduleTracker && allocation.rescheduleTracker.Events) || []; 80 81 let rescheduleTime; 82 if (previousEvents.length) { 83 const lastEvent = previousEvents[previousEvents.length - 1]; 84 rescheduleTime = moment(lastEvent.RescheduleTime / 1000000).add(5, 'minutes'); 85 } else { 86 rescheduleTime = faker.date.past(2 / 365, REF_TIME); 87 } 88 89 rescheduleTime *= 1000000; 90 91 const rescheduleTracker = { 92 Events: previousEvents.concat([ 93 { 94 PrevAllocID: allocation.id, 95 PrevNodeID: null, //allocation.node.id, 96 RescheduleTime: rescheduleTime, 97 }, 98 ]), 99 }; 100 101 let nextAllocation; 102 if (attempts > 0) { 103 nextAllocation = server.create('allocation', 'rescheduled', { 104 rescheduleAttempts: Math.max(attempts, 0), 105 rescheduleSuccess: allocation.rescheduleSuccess, 106 previousAllocation: allocation.id, 107 shallow: allocation.shallow, 108 clientStatus: 'failed', 109 rescheduleTracker, 110 followupEvalId: server.create('evaluation', { 111 waitUntil: rescheduleTime, 112 }).id, 113 }); 114 } else { 115 nextAllocation = server.create('allocation', { 116 previousAllocation: allocation.id, 117 clientStatus: allocation.rescheduleSuccess ? 'running' : 'failed', 118 shallow: allocation.shallow, 119 rescheduleTracker, 120 }); 121 } 122 123 allocation.update({ nextAllocation: nextAllocation.id, clientStatus: 'failed' }); 124 }, 125 }), 126 127 preempted: trait({ 128 afterCreate(allocation, server) { 129 const preempter = server.create('allocation', { preemptedAllocations: [allocation.id] }); 130 allocation.update({ preemptedByAllocation: preempter.id }); 131 }, 132 }), 133 134 preempter: trait({ 135 afterCreate(allocation, server) { 136 const preempted = server.create('allocation', { preemptedByAllocation: allocation.id }); 137 allocation.update({ preemptedAllocations: [preempted.id] }); 138 }, 139 }), 140 141 afterCreate(allocation, server) { 142 Ember.assert( 143 '[Mirage] No jobs! make sure jobs are created before allocations', 144 server.db.jobs.length 145 ); 146 Ember.assert( 147 '[Mirage] No nodes! make sure nodes are created before allocations', 148 server.db.nodes.length 149 ); 150 151 const job = allocation.jobId ? server.db.jobs.find(allocation.jobId) : pickOne(server.db.jobs); 152 const namespace = allocation.namespace || job.namespace; 153 const node = allocation.nodeId 154 ? server.db.nodes.find(allocation.nodeId) 155 : pickOne(server.db.nodes); 156 const taskGroup = allocation.taskGroup 157 ? server.db.taskGroups.findBy({ name: allocation.taskGroup }) 158 : pickOne(server.db.taskGroups.where({ jobId: job.id })); 159 160 allocation.update({ 161 namespace, 162 jobId: job.id, 163 nodeId: node.id, 164 taskStateIds: [], 165 taskResourceIds: [], 166 taskGroup: taskGroup.name, 167 name: allocation.name || `${taskGroup.name}.[${faker.random.number(10)}]`, 168 }); 169 170 if (!allocation.shallow) { 171 const states = taskGroup.taskIds.map(id => 172 server.create('task-state', { 173 allocation, 174 name: server.db.tasks.find(id).name, 175 }) 176 ); 177 178 const resources = taskGroup.taskIds.map(id => 179 server.create('task-resource', { 180 allocation, 181 name: server.db.tasks.find(id).name, 182 }) 183 ); 184 185 allocation.update({ 186 taskStateIds: allocation.clientStatus === 'pending' ? [] : states.mapBy('id'), 187 taskResourceIds: allocation.clientStatus === 'pending' ? [] : resources.mapBy('id'), 188 }); 189 190 // Each allocation has a corresponding allocation stats running on some client. 191 // Create that record, even though it's not a relationship. 192 server.create('client-allocation-stat', { 193 id: allocation.id, 194 _taskNames: states.mapBy('name'), 195 }); 196 } 197 }, 198 });