github.com/blixtra/nomad@v0.7.2-0.20171221000451-da9a1d7bb050/ui/tests/acceptance/task-group-detail-test.js (about)

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