github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/ui/tests/integration/components/topo-viz-test.js (about)

     1  import { module, test } from 'qunit';
     2  import { triggerEvent } from '@ember/test-helpers';
     3  import { setupRenderingTest } from 'ember-qunit';
     4  import hbs from 'htmlbars-inline-precompile';
     5  import { componentA11yAudit } from 'nomad-ui/tests/helpers/a11y-audit';
     6  import { create } from 'ember-cli-page-object';
     7  import { setupMirage } from 'ember-cli-mirage/test-support';
     8  import sinon from 'sinon';
     9  import faker from 'nomad-ui/mirage/faker';
    10  import topoVizPageObject from 'nomad-ui/tests/pages/components/topo-viz';
    11  
    12  const TopoViz = create(topoVizPageObject());
    13  
    14  const alloc = (nodeId, jobId, taskGroupName, memory, cpu, props = {}) => ({
    15    id: faker.random.uuid(),
    16    taskGroupName,
    17    isScheduled: true,
    18    allocatedResources: {
    19      cpu,
    20      memory,
    21    },
    22    belongsTo: type => ({
    23      id: () => (type === 'job' ? jobId : nodeId),
    24    }),
    25    ...props,
    26  });
    27  
    28  const node = (datacenter, id, memory, cpu) => ({
    29    datacenter,
    30    id,
    31    resources: { memory, cpu },
    32  });
    33  
    34  module('Integration | Component | TopoViz', function(hooks) {
    35    setupRenderingTest(hooks);
    36    setupMirage(hooks);
    37  
    38    const commonTemplate = hbs`
    39      <TopoViz
    40        @nodes={{this.nodes}}
    41        @allocations={{this.allocations}}
    42        @onAllocationSelect={{this.onAllocationSelect}}
    43        @onNodeSelect={{this.onNodeSelect}}
    44        @onDataError={{this.onDataError}} />
    45    `;
    46  
    47    test('presents as a FlexMasonry of datacenters', async function(assert) {
    48      this.setProperties({
    49        nodes: [node('dc1', 'node0', 1000, 500), node('dc2', 'node1', 1000, 500)],
    50  
    51        allocations: [
    52          alloc('node0', 'job1', 'group', 100, 100),
    53          alloc('node0', 'job1', 'group', 100, 100),
    54          alloc('node1', 'job1', 'group', 100, 100),
    55        ],
    56      });
    57  
    58      await this.render(commonTemplate);
    59  
    60      assert.equal(TopoViz.datacenters.length, 2);
    61      assert.equal(TopoViz.datacenters[0].nodes.length, 1);
    62      assert.equal(TopoViz.datacenters[1].nodes.length, 1);
    63      assert.equal(TopoViz.datacenters[0].nodes[0].memoryRects.length, 2);
    64      assert.equal(TopoViz.datacenters[1].nodes[0].memoryRects.length, 1);
    65  
    66      await componentA11yAudit(this.element, assert);
    67    });
    68  
    69    test('clicking on a node in a deeply nested TopoViz::Node will toggle node selection and call @onNodeSelect', async function(assert) {
    70      this.setProperties({
    71        // TopoViz must be dense for node selection to be a feature
    72        nodes: Array(55)
    73          .fill(null)
    74          .map((_, index) => node('dc1', `node${index}`, 1000, 500)),
    75        allocations: [],
    76        onNodeSelect: sinon.spy(),
    77      });
    78  
    79      await this.render(commonTemplate);
    80  
    81      await TopoViz.datacenters[0].nodes[0].selectNode();
    82      assert.ok(this.onNodeSelect.calledOnce);
    83      assert.equal(this.onNodeSelect.getCall(0).args[0].node, this.nodes[0]);
    84  
    85      await TopoViz.datacenters[0].nodes[0].selectNode();
    86      assert.ok(this.onNodeSelect.calledTwice);
    87      assert.equal(this.onNodeSelect.getCall(1).args[0], null);
    88    });
    89  
    90    test('clicking on an allocation in a deeply nested TopoViz::Node will update the topology object with selections and call @onAllocationSelect and @onNodeSelect', async function(assert) {
    91      this.setProperties({
    92        nodes: [node('dc1', 'node0', 1000, 500)],
    93        allocations: [alloc('node0', 'job1', 'group', 100, 100)],
    94        onNodeSelect: sinon.spy(),
    95        onAllocationSelect: sinon.spy(),
    96      });
    97  
    98      await this.render(commonTemplate);
    99  
   100      await TopoViz.datacenters[0].nodes[0].memoryRects[0].select();
   101      assert.ok(this.onAllocationSelect.calledOnce);
   102      assert.equal(this.onAllocationSelect.getCall(0).args[0], this.allocations[0]);
   103      assert.ok(this.onNodeSelect.calledOnce);
   104  
   105      await TopoViz.datacenters[0].nodes[0].memoryRects[0].select();
   106      assert.ok(this.onAllocationSelect.calledTwice);
   107      assert.equal(this.onAllocationSelect.getCall(1).args[0], null);
   108      assert.ok(this.onNodeSelect.calledTwice);
   109      assert.ok(this.onNodeSelect.alwaysCalledWith(null));
   110    });
   111  
   112    test('clicking on an allocation in a deeply nested TopoViz::Node will associate sibling allocations with curves', async function(assert) {
   113      this.setProperties({
   114        nodes: [
   115          node('dc1', 'node0', 1000, 500),
   116          node('dc1', 'node1', 1000, 500),
   117          node('dc1', 'node2', 1000, 500),
   118          node('dc2', 'node3', 1000, 500),
   119          node('dc2', 'node4', 1000, 500),
   120          node('dc2', 'node5', 1000, 500),
   121        ],
   122        allocations: [
   123          alloc('node0', 'job1', 'group', 100, 100),
   124          alloc('node0', 'job1', 'group', 100, 100),
   125          alloc('node1', 'job1', 'group', 100, 100),
   126          alloc('node2', 'job1', 'group', 100, 100),
   127          alloc('node0', 'job1', 'groupTwo', 100, 100),
   128          alloc('node1', 'job2', 'group', 100, 100),
   129          alloc('node2', 'job2', 'groupTwo', 100, 100),
   130        ],
   131        onNodeSelect: sinon.spy(),
   132        onAllocationSelect: sinon.spy(),
   133      });
   134  
   135      const selectedAllocations = this.allocations.filter(
   136        alloc => alloc.belongsTo('job').id() === 'job1' && alloc.taskGroupName === 'group'
   137      );
   138  
   139      await this.render(commonTemplate);
   140  
   141      assert.notOk(TopoViz.allocationAssociationsArePresent);
   142  
   143      await TopoViz.datacenters[0].nodes[0].memoryRects[0].select();
   144  
   145      assert.ok(TopoViz.allocationAssociationsArePresent);
   146      assert.equal(TopoViz.allocationAssociations.length, selectedAllocations.length * 2);
   147  
   148      // Lines get redrawn when the window resizes; make sure the lines persist.
   149      await triggerEvent(window, 'resize');
   150      assert.equal(TopoViz.allocationAssociations.length, selectedAllocations.length * 2);
   151  
   152      await TopoViz.datacenters[0].nodes[0].memoryRects[0].select();
   153      assert.notOk(TopoViz.allocationAssociationsArePresent);
   154    });
   155  
   156    test('when the count of sibling allocations is high enough relative to the node count, curves are not rendered', async function(assert) {
   157      this.setProperties({
   158        nodes: [node('dc1', 'node0', 1000, 500), node('dc1', 'node1', 1000, 500)],
   159        allocations: [
   160          // There need to be at least 10 sibling allocations to trigger this behavior
   161          alloc('node0', 'job1', 'group', 100, 100),
   162          alloc('node0', 'job1', 'group', 100, 100),
   163          alloc('node0', 'job1', 'group', 100, 100),
   164          alloc('node0', 'job1', 'group', 100, 100),
   165          alloc('node0', 'job1', 'group', 100, 100),
   166          alloc('node0', 'job1', 'group', 100, 100),
   167          alloc('node1', 'job1', 'group', 100, 100),
   168          alloc('node1', 'job1', 'group', 100, 100),
   169          alloc('node1', 'job1', 'group', 100, 100),
   170          alloc('node1', 'job1', 'group', 100, 100),
   171          alloc('node1', 'job1', 'group', 100, 100),
   172          alloc('node1', 'job1', 'group', 100, 100),
   173          alloc('node0', 'job1', 'groupTwo', 100, 100),
   174        ],
   175        onNodeSelect: sinon.spy(),
   176        onAllocationSelect: sinon.spy(),
   177      });
   178  
   179      await this.render(commonTemplate);
   180      assert.notOk(TopoViz.allocationAssociationsArePresent);
   181  
   182      await TopoViz.datacenters[0].nodes[0].memoryRects[0].select();
   183      assert.equal(TopoViz.allocationAssociations.length, 0);
   184  
   185      // Lines get redrawn when the window resizes; make sure that doesn't make the lines show up again
   186      await triggerEvent(window, 'resize');
   187      assert.equal(TopoViz.allocationAssociations.length, 0);
   188    });
   189  
   190    test('when one or more nodes are missing the resources property, those nodes are filtered out of the topology view and onDataError is called', async function(assert) {
   191      const badNode = node('dc1', 'node0', 1000, 500);
   192      delete badNode.resources;
   193  
   194      this.setProperties({
   195        nodes: [badNode, node('dc1', 'node1', 1000, 500)],
   196        allocations: [
   197          alloc('node0', 'job1', 'group', 100, 100),
   198          alloc('node0', 'job1', 'group', 100, 100),
   199          alloc('node1', 'job1', 'group', 100, 100),
   200          alloc('node1', 'job1', 'group', 100, 100),
   201          alloc('node0', 'job1', 'groupTwo', 100, 100),
   202        ],
   203        onNodeSelect: sinon.spy(),
   204        onAllocationSelect: sinon.spy(),
   205        onDataError: sinon.spy(),
   206      });
   207  
   208      await this.render(commonTemplate);
   209  
   210      assert.ok(this.onDataError.calledOnce);
   211      assert.deepEqual(this.onDataError.getCall(0).args[0], [
   212        {
   213          type: 'filtered-nodes',
   214          context: [this.nodes[0]],
   215        },
   216      ]);
   217  
   218      assert.equal(TopoViz.datacenters[0].nodes.length, 1);
   219    });
   220  });