11cb0ef41Sopenharmony_ci// In this benchmark, we connect a client to the server, and write
21cb0ef41Sopenharmony_ci// as many bytes as we can in the specified time (default = 10s)
31cb0ef41Sopenharmony_ci'use strict';
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciconst common = require('../common.js');
61cb0ef41Sopenharmony_ciconst util = require('util');
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci// If there are dur=N and len=N args, then
91cb0ef41Sopenharmony_ci// run the function with those settings.
101cb0ef41Sopenharmony_ci// If not, then queue up a bunch of child processes.
111cb0ef41Sopenharmony_ciconst bench = common.createBenchmark(main, {
121cb0ef41Sopenharmony_ci  len: [102400, 1024 * 1024 * 16],
131cb0ef41Sopenharmony_ci  type: ['utf', 'asc', 'buf'],
141cb0ef41Sopenharmony_ci  dur: [5],
151cb0ef41Sopenharmony_ci}, {
161cb0ef41Sopenharmony_ci  test: { len: 1024 },
171cb0ef41Sopenharmony_ci  flags: [ '--expose-internals', '--no-warnings' ],
181cb0ef41Sopenharmony_ci});
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_cifunction main({ dur, len, type }) {
211cb0ef41Sopenharmony_ci  const {
221cb0ef41Sopenharmony_ci    TCP,
231cb0ef41Sopenharmony_ci    TCPConnectWrap,
241cb0ef41Sopenharmony_ci    constants: TCPConstants,
251cb0ef41Sopenharmony_ci  } = common.binding('tcp_wrap');
261cb0ef41Sopenharmony_ci  const { WriteWrap } = common.binding('stream_wrap');
271cb0ef41Sopenharmony_ci  const PORT = common.PORT;
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ci  const serverHandle = new TCP(TCPConstants.SERVER);
301cb0ef41Sopenharmony_ci  let err = serverHandle.bind('127.0.0.1', PORT);
311cb0ef41Sopenharmony_ci  if (err)
321cb0ef41Sopenharmony_ci    fail(err, 'bind');
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci  err = serverHandle.listen(511);
351cb0ef41Sopenharmony_ci  if (err)
361cb0ef41Sopenharmony_ci    fail(err, 'listen');
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci  serverHandle.onconnection = function(err, clientHandle) {
391cb0ef41Sopenharmony_ci    if (err)
401cb0ef41Sopenharmony_ci      fail(err, 'connect');
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci    let chunk;
431cb0ef41Sopenharmony_ci    switch (type) {
441cb0ef41Sopenharmony_ci      case 'buf':
451cb0ef41Sopenharmony_ci        chunk = Buffer.alloc(len, 'x');
461cb0ef41Sopenharmony_ci        break;
471cb0ef41Sopenharmony_ci      case 'utf':
481cb0ef41Sopenharmony_ci        chunk = 'ü'.repeat(len / 2);
491cb0ef41Sopenharmony_ci        break;
501cb0ef41Sopenharmony_ci      case 'asc':
511cb0ef41Sopenharmony_ci        chunk = 'x'.repeat(len);
521cb0ef41Sopenharmony_ci        break;
531cb0ef41Sopenharmony_ci      default:
541cb0ef41Sopenharmony_ci        throw new Error(`invalid type: ${type}`);
551cb0ef41Sopenharmony_ci    }
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci    clientHandle.readStart();
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ci    while (clientHandle.writeQueueSize === 0)
601cb0ef41Sopenharmony_ci      write();
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci    function write() {
631cb0ef41Sopenharmony_ci      const writeReq = new WriteWrap();
641cb0ef41Sopenharmony_ci      writeReq.async = false;
651cb0ef41Sopenharmony_ci      writeReq.oncomplete = afterWrite;
661cb0ef41Sopenharmony_ci      let err;
671cb0ef41Sopenharmony_ci      switch (type) {
681cb0ef41Sopenharmony_ci        case 'buf':
691cb0ef41Sopenharmony_ci          err = clientHandle.writeBuffer(writeReq, chunk);
701cb0ef41Sopenharmony_ci          break;
711cb0ef41Sopenharmony_ci        case 'utf':
721cb0ef41Sopenharmony_ci          err = clientHandle.writeUtf8String(writeReq, chunk);
731cb0ef41Sopenharmony_ci          break;
741cb0ef41Sopenharmony_ci        case 'asc':
751cb0ef41Sopenharmony_ci          err = clientHandle.writeAsciiString(writeReq, chunk);
761cb0ef41Sopenharmony_ci          break;
771cb0ef41Sopenharmony_ci      }
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci      if (err) {
801cb0ef41Sopenharmony_ci        fail(err, 'write');
811cb0ef41Sopenharmony_ci      } else if (!writeReq.async) {
821cb0ef41Sopenharmony_ci        process.nextTick(() => {
831cb0ef41Sopenharmony_ci          afterWrite(0, clientHandle);
841cb0ef41Sopenharmony_ci        });
851cb0ef41Sopenharmony_ci      }
861cb0ef41Sopenharmony_ci    }
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci    function afterWrite(status, handle) {
891cb0ef41Sopenharmony_ci      if (status)
901cb0ef41Sopenharmony_ci        fail(status, 'write');
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci      while (clientHandle.writeQueueSize === 0)
931cb0ef41Sopenharmony_ci        write();
941cb0ef41Sopenharmony_ci    }
951cb0ef41Sopenharmony_ci  };
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci  client(dur);
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci  function fail(err, syscall) {
1001cb0ef41Sopenharmony_ci    throw util._errnoException(err, syscall);
1011cb0ef41Sopenharmony_ci  }
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ci  function client(dur) {
1041cb0ef41Sopenharmony_ci    const clientHandle = new TCP(TCPConstants.SOCKET);
1051cb0ef41Sopenharmony_ci    const connectReq = new TCPConnectWrap();
1061cb0ef41Sopenharmony_ci    const err = clientHandle.connect(connectReq, '127.0.0.1', PORT);
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci    if (err)
1091cb0ef41Sopenharmony_ci      fail(err, 'connect');
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_ci    connectReq.oncomplete = function() {
1121cb0ef41Sopenharmony_ci      let bytes = 0;
1131cb0ef41Sopenharmony_ci      clientHandle.onread = function(buffer) {
1141cb0ef41Sopenharmony_ci        // We're not expecting to ever get an EOF from the client.
1151cb0ef41Sopenharmony_ci        // Just lots of data forever.
1161cb0ef41Sopenharmony_ci        if (!buffer)
1171cb0ef41Sopenharmony_ci          fail('read');
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci        // Don't slice the buffer. The point of this is to isolate, not
1201cb0ef41Sopenharmony_ci        // simulate real traffic.
1211cb0ef41Sopenharmony_ci        bytes += buffer.byteLength;
1221cb0ef41Sopenharmony_ci      };
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci      clientHandle.readStart();
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ci      // The meat of the benchmark is right here:
1271cb0ef41Sopenharmony_ci      bench.start();
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci      setTimeout(() => {
1301cb0ef41Sopenharmony_ci        // report in Gb/sec
1311cb0ef41Sopenharmony_ci        bench.end((bytes * 8) / (1024 * 1024 * 1024));
1321cb0ef41Sopenharmony_ci        process.exit(0);
1331cb0ef41Sopenharmony_ci      }, dur * 1000);
1341cb0ef41Sopenharmony_ci    };
1351cb0ef41Sopenharmony_ci  }
1361cb0ef41Sopenharmony_ci}
137