github.com/aminovpavel/nomad@v0.11.8/ui/tests/acceptance/volume-detail-test.js (about)

     1  import { module, test } from 'qunit';
     2  import { currentURL } from '@ember/test-helpers';
     3  import { setupApplicationTest } from 'ember-qunit';
     4  import { setupMirage } from 'ember-cli-mirage/test-support';
     5  import moment from 'moment';
     6  import { formatBytes } from 'nomad-ui/helpers/format-bytes';
     7  import VolumeDetail from 'nomad-ui/tests/pages/storage/volumes/detail';
     8  
     9  const assignWriteAlloc = (volume, alloc) => {
    10    volume.writeAllocs.add(alloc);
    11    volume.save();
    12  };
    13  
    14  const assignReadAlloc = (volume, alloc) => {
    15    volume.readAllocs.add(alloc);
    16    volume.save();
    17  };
    18  
    19  module('Acceptance | volume detail', function(hooks) {
    20    setupApplicationTest(hooks);
    21    setupMirage(hooks);
    22  
    23    let volume;
    24  
    25    hooks.beforeEach(function() {
    26      server.create('node');
    27      server.create('csi-plugin', { createVolumes: false });
    28      volume = server.create('csi-volume');
    29    });
    30  
    31    test('/csi/volumes/:id should have a breadcrumb trail linking back to Volumes and Storage', async function(assert) {
    32      await VolumeDetail.visit({ id: volume.id });
    33  
    34      assert.equal(VolumeDetail.breadcrumbFor('csi.index').text, 'Storage');
    35      assert.equal(VolumeDetail.breadcrumbFor('csi.volumes').text, 'Volumes');
    36      assert.equal(VolumeDetail.breadcrumbFor('csi.volumes.volume').text, volume.name);
    37    });
    38  
    39    test('/csi/volumes/:id should show the volume name in the title', async function(assert) {
    40      await VolumeDetail.visit({ id: volume.id });
    41  
    42      assert.equal(document.title, `CSI Volume ${volume.name} - Nomad`);
    43      assert.equal(VolumeDetail.title, volume.name);
    44    });
    45  
    46    test('/csi/volumes/:id should list additional details for the volume below the title', async function(assert) {
    47      await VolumeDetail.visit({ id: volume.id });
    48  
    49      assert.ok(VolumeDetail.health.includes(volume.schedulable ? 'Schedulable' : 'Unschedulable'));
    50      assert.ok(VolumeDetail.provider.includes(volume.provider));
    51      assert.ok(VolumeDetail.externalId.includes(volume.externalId));
    52      assert.notOk(
    53        VolumeDetail.hasNamespace,
    54        'Namespace is omitted when there is only one namespace'
    55      );
    56    });
    57  
    58    test('/csi/volumes/:id should list all write allocations the volume is attached to', async function(assert) {
    59      const writeAllocations = server.createList('allocation', 2);
    60      const readAllocations = server.createList('allocation', 3);
    61      writeAllocations.forEach(alloc => assignWriteAlloc(volume, alloc));
    62      readAllocations.forEach(alloc => assignReadAlloc(volume, alloc));
    63  
    64      await VolumeDetail.visit({ id: volume.id });
    65  
    66      assert.equal(VolumeDetail.writeAllocations.length, writeAllocations.length);
    67      writeAllocations
    68        .sortBy('modifyIndex')
    69        .reverse()
    70        .forEach((allocation, idx) => {
    71          assert.equal(allocation.id, VolumeDetail.writeAllocations.objectAt(idx).id);
    72        });
    73    });
    74  
    75    test('/csi/volumes/:id should list all read allocations the volume is attached to', async function(assert) {
    76      const writeAllocations = server.createList('allocation', 2);
    77      const readAllocations = server.createList('allocation', 3);
    78      writeAllocations.forEach(alloc => assignWriteAlloc(volume, alloc));
    79      readAllocations.forEach(alloc => assignReadAlloc(volume, alloc));
    80  
    81      await VolumeDetail.visit({ id: volume.id });
    82  
    83      assert.equal(VolumeDetail.readAllocations.length, readAllocations.length);
    84      readAllocations
    85        .sortBy('modifyIndex')
    86        .reverse()
    87        .forEach((allocation, idx) => {
    88          assert.equal(allocation.id, VolumeDetail.readAllocations.objectAt(idx).id);
    89        });
    90    });
    91  
    92    test('each allocation should have high-level details for the allocation', async function(assert) {
    93      const allocation = server.create('allocation', { clientStatus: 'running' });
    94      assignWriteAlloc(volume, allocation);
    95  
    96      const allocStats = server.db.clientAllocationStats.find(allocation.id);
    97      const taskGroup = server.db.taskGroups.findBy({
    98        name: allocation.taskGroup,
    99        jobId: allocation.jobId,
   100      });
   101  
   102      const tasks = taskGroup.taskIds.map(id => server.db.tasks.find(id));
   103      const cpuUsed = tasks.reduce((sum, task) => sum + task.Resources.CPU, 0);
   104      const memoryUsed = tasks.reduce((sum, task) => sum + task.Resources.MemoryMB, 0);
   105  
   106      await VolumeDetail.visit({ id: volume.id });
   107  
   108      VolumeDetail.writeAllocations.objectAt(0).as(allocationRow => {
   109        assert.equal(allocationRow.shortId, allocation.id.split('-')[0], 'Allocation short ID');
   110        assert.equal(
   111          allocationRow.createTime,
   112          moment(allocation.createTime / 1000000).format('MMM DD HH:mm:ss ZZ'),
   113          'Allocation create time'
   114        );
   115        assert.equal(
   116          allocationRow.modifyTime,
   117          moment(allocation.modifyTime / 1000000).fromNow(),
   118          'Allocation modify time'
   119        );
   120        assert.equal(allocationRow.status, allocation.clientStatus, 'Client status');
   121        assert.equal(allocationRow.job, server.db.jobs.find(allocation.jobId).name, 'Job name');
   122        assert.ok(allocationRow.taskGroup, 'Task group name');
   123        assert.ok(allocationRow.jobVersion, 'Job Version');
   124        assert.equal(
   125          allocationRow.client,
   126          server.db.nodes.find(allocation.nodeId).id.split('-')[0],
   127          'Node ID'
   128        );
   129        assert.equal(
   130          allocationRow.cpu,
   131          Math.floor(allocStats.resourceUsage.CpuStats.TotalTicks) / cpuUsed,
   132          'CPU %'
   133        );
   134        assert.equal(
   135          allocationRow.cpuTooltip,
   136          `${Math.floor(allocStats.resourceUsage.CpuStats.TotalTicks)} / ${cpuUsed} MHz`,
   137          'Detailed CPU information is in a tooltip'
   138        );
   139        assert.equal(
   140          allocationRow.mem,
   141          allocStats.resourceUsage.MemoryStats.RSS / 1024 / 1024 / memoryUsed,
   142          'Memory used'
   143        );
   144        assert.equal(
   145          allocationRow.memTooltip,
   146          `${formatBytes([allocStats.resourceUsage.MemoryStats.RSS])} / ${memoryUsed} MiB`,
   147          'Detailed memory information is in a tooltip'
   148        );
   149      });
   150    });
   151  
   152    test('each allocation should link to the allocation detail page', async function(assert) {
   153      const allocation = server.create('allocation');
   154      assignWriteAlloc(volume, allocation);
   155  
   156      await VolumeDetail.visit({ id: volume.id });
   157      await VolumeDetail.writeAllocations.objectAt(0).visit();
   158  
   159      assert.equal(currentURL(), `/allocations/${allocation.id}`);
   160    });
   161  
   162    test('when there are no write allocations, the table presents an empty state', async function(assert) {
   163      await VolumeDetail.visit({ id: volume.id });
   164  
   165      assert.ok(VolumeDetail.writeTableIsEmpty);
   166      assert.equal(VolumeDetail.writeEmptyState.headline, 'No Write Allocations');
   167    });
   168  
   169    test('when there are no read allocations, the table presents an empty state', async function(assert) {
   170      await VolumeDetail.visit({ id: volume.id });
   171  
   172      assert.ok(VolumeDetail.readTableIsEmpty);
   173      assert.equal(VolumeDetail.readEmptyState.headline, 'No Read Allocations');
   174    });
   175  
   176    test('the constraints table shows access mode and attachment mode', async function(assert) {
   177      await VolumeDetail.visit({ id: volume.id });
   178  
   179      assert.equal(VolumeDetail.constraints.accessMode, volume.accessMode);
   180      assert.equal(VolumeDetail.constraints.attachmentMode, volume.attachmentMode);
   181    });
   182  });
   183  
   184  // Namespace test: details shows the namespace
   185  module('Acceptance | volume detail (with namespaces)', function(hooks) {
   186    setupApplicationTest(hooks);
   187    setupMirage(hooks);
   188  
   189    let volume;
   190  
   191    hooks.beforeEach(function() {
   192      server.createList('namespace', 2);
   193      server.create('node');
   194      server.create('csi-plugin', { createVolumes: false });
   195      volume = server.create('csi-volume');
   196    });
   197  
   198    test('/csi/volumes/:id detail ribbon includes the namespace of the volume', async function(assert) {
   199      await VolumeDetail.visit({ id: volume.id });
   200  
   201      assert.ok(VolumeDetail.hasNamespace);
   202      assert.ok(VolumeDetail.namespace.includes(volume.namespaceId || 'default'));
   203    });
   204  });