github.com/zoomfoo/nomad@v0.8.5-0.20180907175415-f28fd3a1a056/ui/tests/acceptance/task-group-detail-test.js (about)

     1  import { currentURL } from 'ember-native-dom-helpers';
     2  import { test } from 'qunit';
     3  import moduleForAcceptance from 'nomad-ui/tests/helpers/module-for-acceptance';
     4  import { formatBytes } from 'nomad-ui/helpers/format-bytes';
     5  import TaskGroup from 'nomad-ui/tests/pages/jobs/job/task-group';
     6  import JobsList from 'nomad-ui/tests/pages/jobs/list';
     7  import moment from 'moment';
     8  
     9  let job;
    10  let taskGroup;
    11  let tasks;
    12  let allocations;
    13  
    14  const sum = (total, n) => total + n;
    15  
    16  moduleForAcceptance('Acceptance | task group detail', {
    17    beforeEach() {
    18      server.create('agent');
    19      server.create('node', 'forceIPv4');
    20  
    21      job = server.create('job', {
    22        groupsCount: 2,
    23        createAllocations: false,
    24      });
    25  
    26      const taskGroups = server.db.taskGroups.where({ jobId: job.id });
    27      taskGroup = taskGroups[0];
    28  
    29      tasks = taskGroup.taskIds.map(id => server.db.tasks.find(id));
    30  
    31      server.create('node', 'forceIPv4');
    32  
    33      allocations = server.createList('allocation', 2, {
    34        jobId: job.id,
    35        taskGroup: taskGroup.name,
    36      });
    37  
    38      // Allocations associated to a different task group on the job to
    39      // assert that they aren't showing up in on this page in error.
    40      server.createList('allocation', 3, {
    41        jobId: job.id,
    42        taskGroup: taskGroups[1].name,
    43      });
    44  
    45      // Set a static name to make the search test deterministic
    46      server.db.allocations.forEach(alloc => {
    47        alloc.name = 'aaaaa';
    48      });
    49  
    50      // Mark the first alloc as rescheduled
    51      allocations[0].update({
    52        nextAllocation: allocations[1].id,
    53      });
    54      allocations[1].update({
    55        previousAllocation: allocations[0].id,
    56      });
    57  
    58      TaskGroup.visit({ id: job.id, name: taskGroup.name });
    59    },
    60  });
    61  
    62  test('/jobs/:id/:task-group should list high-level metrics for the allocation', function(assert) {
    63    const totalCPU = tasks.mapBy('Resources.CPU').reduce(sum, 0);
    64    const totalMemory = tasks.mapBy('Resources.MemoryMB').reduce(sum, 0);
    65    const totalDisk = taskGroup.ephemeralDisk.SizeMB;
    66  
    67    assert.equal(TaskGroup.tasksCount, `# Tasks ${tasks.length}`, '# Tasks');
    68    assert.equal(
    69      TaskGroup.cpu,
    70      `Reserved CPU ${totalCPU} MHz`,
    71      'Aggregated CPU reservation for all tasks'
    72    );
    73    assert.equal(
    74      TaskGroup.mem,
    75      `Reserved Memory ${totalMemory} MiB`,
    76      'Aggregated Memory reservation for all tasks'
    77    );
    78    assert.equal(
    79      TaskGroup.disk,
    80      `Reserved Disk ${totalDisk} MiB`,
    81      'Aggregated Disk reservation for all tasks'
    82    );
    83  });
    84  
    85  test('/jobs/:id/:task-group should have breadcrumbs for job and jobs', function(assert) {
    86    assert.equal(TaskGroup.breadcrumbFor('jobs.index').text, 'Jobs', 'First breadcrumb says jobs');
    87    assert.equal(
    88      TaskGroup.breadcrumbFor('jobs.job.index').text,
    89      job.name,
    90      'Second breadcrumb says the job name'
    91    );
    92    assert.equal(
    93      TaskGroup.breadcrumbFor('jobs.job.task-group').text,
    94      taskGroup.name,
    95      'Third breadcrumb says the job name'
    96    );
    97  });
    98  
    99  test('/jobs/:id/:task-group first breadcrumb should link to jobs', function(assert) {
   100    TaskGroup.breadcrumbFor('jobs.index').visit();
   101    andThen(() => {
   102      assert.equal(currentURL(), '/jobs', 'First breadcrumb links back to jobs');
   103    });
   104  });
   105  
   106  test('/jobs/:id/:task-group second breadcrumb should link to the job for the task group', function(assert) {
   107    TaskGroup.breadcrumbFor('jobs.job.index').visit();
   108    andThen(() => {
   109      assert.equal(
   110        currentURL(),
   111        `/jobs/${job.id}`,
   112        'Second breadcrumb links back to the job for the task group'
   113      );
   114    });
   115  });
   116  
   117  test('/jobs/:id/:task-group should list one page of allocations for the task group', function(assert) {
   118    server.createList('allocation', TaskGroup.pageSize, {
   119      jobId: job.id,
   120      taskGroup: taskGroup.name,
   121    });
   122  
   123    JobsList.visit();
   124    TaskGroup.visit({ id: job.id, name: taskGroup.name });
   125  
   126    andThen(() => {
   127      assert.ok(
   128        server.db.allocations.where({ jobId: job.id }).length > TaskGroup.pageSize,
   129        'There are enough allocations to invoke pagination'
   130      );
   131  
   132      assert.equal(
   133        TaskGroup.allocations.length,
   134        TaskGroup.pageSize,
   135        'All allocations for the task group'
   136      );
   137    });
   138  });
   139  
   140  test('each allocation should show basic information about the allocation', function(assert) {
   141    const allocation = allocations.sortBy('modifyIndex').reverse()[0];
   142    const allocationRow = TaskGroup.allocations.objectAt(0);
   143  
   144    andThen(() => {
   145      assert.equal(allocationRow.shortId, allocation.id.split('-')[0], 'Allocation short id');
   146      assert.equal(
   147        allocationRow.createTime,
   148        moment(allocation.createTime / 1000000).format('MM/DD HH:mm:ss'),
   149        'Allocation create time'
   150      );
   151      assert.equal(
   152        allocationRow.modifyTime,
   153        moment(allocation.modifyTime / 1000000).fromNow(),
   154        'Allocation modify time'
   155      );
   156      assert.equal(allocationRow.status, allocation.clientStatus, 'Client status');
   157      assert.equal(allocationRow.jobVersion, allocation.jobVersion, 'Job Version');
   158      assert.equal(
   159        allocationRow.client,
   160        server.db.nodes.find(allocation.nodeId).id.split('-')[0],
   161        'Node ID'
   162      );
   163    });
   164  
   165    allocationRow.visitClient();
   166  
   167    andThen(() => {
   168      assert.equal(currentURL(), `/clients/${allocation.nodeId}`, 'Node links to node page');
   169    });
   170  });
   171  
   172  test('each allocation should show stats about the allocation', function(assert) {
   173    const allocation = allocations.sortBy('name')[0];
   174    const allocationRow = TaskGroup.allocations.objectAt(0);
   175  
   176    const allocStats = server.db.clientAllocationStats.find(allocation.id);
   177    const tasks = taskGroup.taskIds.map(id => server.db.tasks.find(id));
   178  
   179    const cpuUsed = tasks.reduce((sum, task) => sum + task.Resources.CPU, 0);
   180    const memoryUsed = tasks.reduce((sum, task) => sum + task.Resources.MemoryMB, 0);
   181  
   182    assert.equal(
   183      allocationRow.cpu,
   184      Math.floor(allocStats.resourceUsage.CpuStats.TotalTicks) / cpuUsed,
   185      'CPU %'
   186    );
   187  
   188    assert.equal(
   189      allocationRow.cpuTooltip,
   190      `${Math.floor(allocStats.resourceUsage.CpuStats.TotalTicks)} / ${cpuUsed} MHz`,
   191      'Detailed CPU information is in a tooltip'
   192    );
   193  
   194    assert.equal(
   195      allocationRow.mem,
   196      allocStats.resourceUsage.MemoryStats.RSS / 1024 / 1024 / memoryUsed,
   197      'Memory used'
   198    );
   199  
   200    assert.equal(
   201      allocationRow.memTooltip,
   202      `${formatBytes([allocStats.resourceUsage.MemoryStats.RSS])} / ${memoryUsed} MiB`,
   203      'Detailed memory information is in a tooltip'
   204    );
   205  });
   206  
   207  test('when the allocation search has no matches, there is an empty message', function(assert) {
   208    TaskGroup.search('zzzzzz');
   209  
   210    andThen(() => {
   211      assert.ok(TaskGroup.isEmpty, 'Empty state is shown');
   212      assert.equal(
   213        TaskGroup.emptyState.headline,
   214        'No Matches',
   215        'Empty state has an appropriate message'
   216      );
   217    });
   218  });
   219  
   220  test('when the allocation has reschedule events, the allocation row is denoted with an icon', function(assert) {
   221    const rescheduleRow = TaskGroup.allocationFor(allocations[0].id);
   222    const normalRow = TaskGroup.allocationFor(allocations[1].id);
   223  
   224    assert.ok(rescheduleRow.rescheduled, 'Reschedule row has a reschedule icon');
   225    assert.notOk(normalRow.rescheduled, 'Normal row has no reschedule icon');
   226  });