github.com/anuvu/nomad@v0.8.7-atom1/ui/tests/acceptance/task-group-detail-test.js (about)

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