github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/ui/tests/integration/components/topo-viz/datacenter-test.js (about)

     1  import { find, render } from '@ember/test-helpers';
     2  import { module, test } from 'qunit';
     3  import { setupRenderingTest } from 'ember-qunit';
     4  import hbs from 'htmlbars-inline-precompile';
     5  import { setupMirage } from 'ember-cli-mirage/test-support';
     6  import { componentA11yAudit } from 'nomad-ui/tests/helpers/a11y-audit';
     7  import { create } from 'ember-cli-page-object';
     8  import sinon from 'sinon';
     9  import faker from 'nomad-ui/mirage/faker';
    10  import topoVizDatacenterPageObject from 'nomad-ui/tests/pages/components/topo-viz/datacenter';
    11  import { formatBytes, formatHertz } from 'nomad-ui/utils/units';
    12  
    13  const TopoVizDatacenter = create(topoVizDatacenterPageObject());
    14  
    15  const nodeGen = (name, datacenter, memory, cpu, allocations = []) => ({
    16    datacenter,
    17    memory,
    18    cpu,
    19    node: { name },
    20    allocations: allocations.map((alloc) => ({
    21      memory: alloc.memory,
    22      cpu: alloc.cpu,
    23      memoryPercent: alloc.memory / memory,
    24      cpuPercent: alloc.cpu / cpu,
    25      allocation: {
    26        id: faker.random.uuid(),
    27        isScheduled: true,
    28      },
    29    })),
    30  });
    31  
    32  // Used in Array#reduce to sum by a property common to an array of objects
    33  const sumBy = (prop) => (sum, obj) => (sum += obj[prop]);
    34  
    35  module('Integration | Component | TopoViz::Datacenter', function (hooks) {
    36    setupRenderingTest(hooks);
    37    setupMirage(hooks);
    38  
    39    const commonProps = (props) => ({
    40      isSingleColumn: true,
    41      isDense: false,
    42      heightScale: () => 50,
    43      onAllocationSelect: sinon.spy(),
    44      onNodeSelect: sinon.spy(),
    45      ...props,
    46    });
    47  
    48    const commonTemplate = hbs`
    49      <TopoViz::Datacenter
    50        @datacenter={{this.datacenter}}
    51        @isSingleColumn={{this.isSingleColumn}}
    52        @isDense={{this.isDense}}
    53        @heightScale={{this.heightScale}}
    54        @onAllocationSelect={{this.onAllocationSelect}}
    55        @onNodeSelect={{this.onNodeSelect}} />
    56    `;
    57  
    58    test('presents as a div with a label and a FlexMasonry with a collection of nodes', async function (assert) {
    59      assert.expect(3);
    60  
    61      this.setProperties(
    62        commonProps({
    63          datacenter: {
    64            name: 'dc1',
    65            nodes: [nodeGen('node-1', 'dc1', 1000, 500)],
    66          },
    67        })
    68      );
    69  
    70      await render(commonTemplate);
    71  
    72      assert.ok(TopoVizDatacenter.isPresent);
    73      assert.equal(TopoVizDatacenter.nodes.length, this.datacenter.nodes.length);
    74  
    75      await componentA11yAudit(this.element, assert);
    76    });
    77  
    78    test('datacenter stats are an aggregate of node stats', async function (assert) {
    79      this.setProperties(
    80        commonProps({
    81          datacenter: {
    82            name: 'dc1',
    83            nodes: [
    84              nodeGen('node-1', 'dc1', 1000, 500, [
    85                { memory: 100, cpu: 300 },
    86                { memory: 200, cpu: 50 },
    87              ]),
    88              nodeGen('node-2', 'dc1', 1500, 100, [
    89                { memory: 50, cpu: 80 },
    90                { memory: 100, cpu: 20 },
    91              ]),
    92              nodeGen('node-3', 'dc1', 2000, 300),
    93              nodeGen('node-4', 'dc1', 3000, 200),
    94            ],
    95          },
    96        })
    97      );
    98  
    99      await render(commonTemplate);
   100  
   101      const allocs = this.datacenter.nodes.reduce(
   102        (allocs, node) => allocs.concat(node.allocations),
   103        []
   104      );
   105      const memoryReserved = allocs.reduce(sumBy('memory'), 0);
   106      const cpuReserved = allocs.reduce(sumBy('cpu'), 0);
   107      const memoryTotal = this.datacenter.nodes.reduce(sumBy('memory'), 0);
   108      const cpuTotal = this.datacenter.nodes.reduce(sumBy('cpu'), 0);
   109  
   110      assert.ok(TopoVizDatacenter.label.includes(this.datacenter.name));
   111      assert.ok(
   112        TopoVizDatacenter.label.includes(`${this.datacenter.nodes.length} Nodes`)
   113      );
   114      assert.ok(TopoVizDatacenter.label.includes(`${allocs.length} Allocs`));
   115      assert.ok(
   116        TopoVizDatacenter.label.includes(
   117          `${formatBytes(memoryReserved, 'MiB')}/${formatBytes(
   118            memoryTotal,
   119            'MiB'
   120          )}`
   121        )
   122      );
   123      assert.ok(
   124        TopoVizDatacenter.label.includes(
   125          `${formatHertz(cpuReserved, 'MHz')}/${formatHertz(cpuTotal, 'MHz')}`
   126        )
   127      );
   128    });
   129  
   130    test('when @isSingleColumn is true, the FlexMasonry layout gets one column, otherwise it gets two', async function (assert) {
   131      this.setProperties(
   132        commonProps({
   133          isSingleColumn: true,
   134          datacenter: {
   135            name: 'dc1',
   136            nodes: [
   137              nodeGen('node-1', 'dc1', 1000, 500),
   138              nodeGen('node-2', 'dc1', 1000, 500),
   139            ],
   140          },
   141        })
   142      );
   143  
   144      await render(commonTemplate);
   145  
   146      assert.ok(find('[data-test-flex-masonry].flex-masonry-columns-1'));
   147  
   148      this.set('isSingleColumn', false);
   149      assert.ok(find('[data-test-flex-masonry].flex-masonry-columns-2'));
   150    });
   151  
   152    test('args get passed down to the TopViz::Node children', async function (assert) {
   153      assert.expect(4);
   154  
   155      const heightSpy = sinon.spy();
   156      this.setProperties(
   157        commonProps({
   158          isDense: true,
   159          heightScale: (...args) => {
   160            heightSpy(...args);
   161            return 50;
   162          },
   163          datacenter: {
   164            name: 'dc1',
   165            nodes: [
   166              nodeGen('node-1', 'dc1', 1000, 500, [{ memory: 100, cpu: 300 }]),
   167            ],
   168          },
   169        })
   170      );
   171  
   172      await render(commonTemplate);
   173  
   174      TopoVizDatacenter.nodes[0].as(async (TopoVizNode) => {
   175        assert.notOk(TopoVizNode.labelIsPresent);
   176        assert.ok(heightSpy.calledWith(this.datacenter.nodes[0].memory));
   177  
   178        await TopoVizNode.selectNode();
   179        assert.ok(this.onNodeSelect.calledWith(this.datacenter.nodes[0]));
   180  
   181        await TopoVizNode.memoryRects[0].select();
   182        assert.ok(
   183          this.onAllocationSelect.calledWith(
   184            this.datacenter.nodes[0].allocations[0]
   185          )
   186        );
   187      });
   188    });
   189  });