// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'dart:zircon';

import 'package:litetest/litetest.dart';

/// Helper method to turn a [String] into a [ByteData] containing the
/// text of the string encoded as UTF-8.
ByteData utf8Bytes(final String text) {
  return ByteData.sublistView(utf8.encode(text));
}

// Take from zircon constants in zircon/errors.h, zircon/rights.h, zircon/types.h
abstract class ZX {
  ZX._();

  static const int OK = 0;
  static const int KOID_INVALID = 0;
  static const int ERR_BAD_HANDLE = -11;
  static const int ERR_SHOULD_WAIT = -22;
  static const int ERR_PEER_CLOSED = -24;
  static const int ERR_ACCESS_DENIED = -30;
  static const int EVENTPAIR_PEER_CLOSED = __ZX_OBJECT_PEER_CLOSED;
  static const int CHANNEL_READABLE = __ZX_OBJECT_READABLE;
  static const int CHANNEL_PEER_CLOSED = __ZX_OBJECT_PEER_CLOSED;
  static const int SOCKET_READABLE = __ZX_OBJECT_READABLE;
  static const int SOCKET_PEER_CLOSED = __ZX_OBJECT_PEER_CLOSED;
  static const int RIGHT_DUPLICATE = 1 << 0;
  static const int RIGHT_TRANSFER = 1 << 1;
  static const int RIGHT_READ = 1 << 2;
  static const int RIGHT_WRITE = 1 << 3;
  static const int RIGHT_GET_PROPERTY = 1 << 6;
  static const int RIGHT_SET_PROPERTY = 1 << 7;
  static const int RIGHT_MAP = 1 << 5;
  static const int RIGHT_SIGNAL = 1 << 12;
  static const int RIGHT_WAIT = 1 << 14;
  static const int RIGHT_INSPECT = 1 << 15;
  static const int RIGHT_SAME_RIGHTS = 1 << 31;
  static const int RIGHTS_BASIC = RIGHT_TRANSFER | RIGHT_DUPLICATE |
                                  RIGHT_WAIT | RIGHT_INSPECT;
  static const int RIGHTS_IO = RIGHT_READ | RIGHT_WRITE;
  static const int RIGHTS_PROPERTY = RIGHT_GET_PROPERTY | RIGHT_SET_PROPERTY;
  static const int DEFAULT_VMO_RIGHTS = RIGHTS_BASIC | RIGHTS_IO |
                                        RIGHTS_PROPERTY | RIGHT_MAP |
                                        RIGHT_SIGNAL;
  static const int OBJ_TYPE_VMO = 3;
  static const int OBJ_TYPE_CHANNEL = 4;
  static const int HANDLE_OP_MOVE = 0;
  static const int HANDLE_OP_DUPLICATE = 1;
  static const int __ZX_OBJECT_READABLE = 1 << 0;
  static const int __ZX_OBJECT_PEER_CLOSED = 1 << 2;
}

void main() {
  group('handle', () {
    test('create and duplicate handles', () {
      final HandlePairResult pair = System.eventpairCreate();
      expect(pair.status, equals(ZX.OK));
      expect(pair.first.isValid, isTrue);
      expect(pair.second.isValid, isTrue);

      final Handle duplicate = pair.first.duplicate(ZX.RIGHT_SAME_RIGHTS);
      expect(duplicate.isValid, isTrue);

      final Handle failedDuplicate = pair.first.duplicate(-1);
      expect(failedDuplicate.isValid, isFalse);
    });

    test('failure invalid rights', () {
      final HandleResult vmo = System.vmoCreate(0);
      expect(vmo.status, equals(ZX.OK));
      final Handle failedDuplicate = vmo.handle.duplicate(-1);
      expect(failedDuplicate.isValid, isFalse);
      expect(vmo.handle.isValid, isTrue);
    });

    test('failure invalid handle', () {
      final Handle handle = Handle.invalid();
      final Handle duplicate = handle.duplicate(ZX.RIGHT_SAME_RIGHTS);
      expect(duplicate.isValid, isFalse);
    });

    test('duplicated handle should have same koid', () {
      final HandlePairResult pair = System.eventpairCreate();
      expect(pair.status, equals(ZX.OK));
      expect(pair.first.isValid, isTrue);
      expect(pair.second.isValid, isTrue);

      final Handle duplicate = pair.first.duplicate(ZX.RIGHT_SAME_RIGHTS);
      expect(duplicate.isValid, isTrue);

      expect(pair.first.koid, duplicate.koid);
    });

    // TODO(fxbug.dev/77599): Simplify once zx_object_get_info is available.
    test('reduced rights', () {
      // Set up handle.
      final HandleResult vmo = System.vmoCreate(2);
      expect(vmo.status, equals(ZX.OK));

      // Duplicate the first handle.
      final Handle duplicate = vmo.handle.duplicate(ZX.RIGHTS_BASIC);
      expect(duplicate.isValid, isTrue);

      // Write bytes to the original handle.
      final ByteData data1 = utf8Bytes('a');
      final int status1 = System.vmoWrite(vmo.handle, 0, data1);
      expect(status1, equals(ZX.OK));

      // Write bytes to the duplicated handle.
      final ByteData data2 = utf8Bytes('b');
      final int status2 = System.vmoWrite(duplicate, 1, data2);
      expect(status2, equals(ZX.ERR_ACCESS_DENIED));

      // Read bytes.
      final ReadResult readResult = System.vmoRead(vmo.handle, 0, 2);
      expect(readResult.status, equals(ZX.OK));
      expect(readResult.numBytes, equals(2));
      expect(readResult.bytes.lengthInBytes, equals(2));
      expect(readResult.bytesAsUTF8String(), equals('a\x00'));
    });

    test('create and replace handles', () {
      final HandlePairResult pair = System.eventpairCreate();
      expect(pair.status, equals(ZX.OK));
      expect(pair.first.isValid, isTrue);
      expect(pair.second.isValid, isTrue);

      final Handle replaced = pair.first.replace(ZX.RIGHT_SAME_RIGHTS);
      expect(replaced.isValid, isTrue);
      expect(pair.first.isValid, isFalse);
    });

    test('failure invalid rights', () {
      final HandleResult vmo = System.vmoCreate(0);
      expect(vmo.status, equals(ZX.OK));
      final Handle failedDuplicate = vmo.handle.replace(-1);
      expect(failedDuplicate.isValid, isFalse);
      expect(vmo.handle.isValid, isFalse);
    });

    test('failure invalid handle', () {
      final Handle handle = Handle.invalid();
      final Handle replaced = handle.replace(ZX.RIGHT_SAME_RIGHTS);
      expect(handle.isValid, isFalse);
      expect(replaced.isValid, isFalse);
    });

    test('transferred handle should have same koid', () {
      final HandlePairResult pair = System.eventpairCreate();
      expect(pair.status, equals(ZX.OK));
      expect(pair.first.isValid, isTrue);
      expect(pair.second.isValid, isTrue);

      final int koid = pair.first.koid;
      final Handle replaced = pair.first.replace(ZX.RIGHT_SAME_RIGHTS);
      expect(replaced.isValid, isTrue);

      expect(koid, replaced.koid);
    });

    // TODO(fxbug.dev/77599): Simplify once zx_object_get_info is available.
    test('reduced rights', () {
      // Set up handle.
      final HandleResult vmo = System.vmoCreate(2);
      expect(vmo.status, equals(ZX.OK));

      // Replace the first handle.
      final Handle duplicate =
          vmo.handle.replace(ZX.RIGHTS_BASIC | ZX.RIGHT_READ);
      expect(duplicate.isValid, isTrue);

      // Write bytes to the original handle.
      final ByteData data1 = utf8Bytes('a');
      final int status1 = System.vmoWrite(vmo.handle, 0, data1);
      expect(status1, equals(ZX.ERR_BAD_HANDLE));

      // Write bytes to the duplicated handle.
      final ByteData data2 = utf8Bytes('b');
      final int status2 = System.vmoWrite(duplicate, 1, data2);
      expect(status2, equals(ZX.ERR_ACCESS_DENIED));

      // Read bytes.
      final ReadResult readResult = System.vmoRead(duplicate, 0, 2);
      expect(readResult.status, equals(ZX.OK));
      expect(readResult.numBytes, equals(2));
      expect(readResult.bytes.lengthInBytes, equals(2));
      expect(readResult.bytesAsUTF8String(), equals('\x00\x00'));
    });

    test('cache koid and invalidate', () {
      final HandleResult vmo = System.vmoCreate(0);
      expect(vmo.status, equals(ZX.OK));
      int originalKoid = vmo.handle.koid;
      expect(originalKoid, notEquals(ZX.KOID_INVALID));
      // Cached koid should be same value.
      expect(originalKoid, equals(vmo.handle.koid));
      vmo.handle.close();
      // koid should be invalidated.
      expect(vmo.handle.koid, equals(ZX.KOID_INVALID));
    });

    test('store the disposition arguments correctly', () {
      final Handle handle = System.channelCreate().first;
      final HandleDisposition disposition = HandleDisposition(1, handle, 2, 3);
      expect(disposition.operation, equals(1));
      expect(disposition.handle, equals(handle));
      expect(disposition.type, equals(2));
      expect(disposition.rights, equals(3));
      expect(disposition.result, equals(ZX.OK));
    });
  });

  group('channel', () {
    test('create channel', () {
      final HandlePairResult pair = System.channelCreate();
      expect(pair.status, equals(ZX.OK));
      expect(pair.first.isValid, isTrue);
      expect(pair.second.isValid, isTrue);
    });

    test('close channel', () {
      final HandlePairResult pair = System.channelCreate();
      expect(pair.first.close(), equals(0));
      expect(pair.first.isValid, isFalse);
      expect(pair.second.isValid, isTrue);
      expect(System.channelWrite(pair.first, ByteData(1), <Handle>[]),
          equals(ZX.ERR_BAD_HANDLE));
      expect(System.channelWrite(pair.second, ByteData(1), <Handle>[]),
          equals(ZX.ERR_PEER_CLOSED));
    });

    test('channel bytes', () {
      final HandlePairResult pair = System.channelCreate();

      // When no data is available, ZX.ERR_SHOULD_WAIT is returned.
      expect(System.channelQueryAndRead(pair.second).status,
          equals(ZX.ERR_SHOULD_WAIT));

      // Write bytes.
      final ByteData data = utf8Bytes('Hello, world');
      final int status = System.channelWrite(pair.first, data, <Handle>[]);
      expect(status, equals(ZX.OK));

      // Read bytes.
      final ReadResult readResult = System.channelQueryAndRead(pair.second);
      expect(readResult.status, equals(ZX.OK));
      expect(readResult.numBytes, equals(data.lengthInBytes));
      expect(readResult.bytes.lengthInBytes, equals(data.lengthInBytes));
      expect(readResult.bytesAsUTF8String(), equals('Hello, world'));
      expect(readResult.handles.length, equals(0));
    });

    test('channel handles', () {
      final HandlePairResult pair = System.channelCreate();
      final ByteData data = utf8Bytes('');
      final HandlePairResult eventPair = System.eventpairCreate();
      final int status =
          System.channelWrite(pair.first, data, <Handle>[eventPair.first]);
      expect(status, equals(ZX.OK));
      expect(eventPair.first.isValid, isFalse);

      final ReadResult readResult = System.channelQueryAndRead(pair.second);
      expect(readResult.status, equals(ZX.OK));
      expect(readResult.numBytes, equals(0));
      expect(readResult.bytes.lengthInBytes, equals(0));
      expect(readResult.bytesAsUTF8String(), equals(''));
      expect(readResult.handles.length, equals(1));
      expect(readResult.handles[0].isValid, isTrue);
    });

    test('async wait channel read', () async {
      final HandlePairResult pair = System.channelCreate();
      final Completer<List<int>> completer = Completer<List<int>>();
      pair.first.asyncWait(ZX.CHANNEL_READABLE, (int status, int pending) {
        completer.complete(<int>[status, pending]);
      });

      expect(completer.isCompleted, isFalse);

      System.channelWrite(pair.second, utf8Bytes('Hi'), <Handle>[]);

      final List<int> result = await completer.future;
      expect(result[0], equals(ZX.OK)); // status
      expect(result[1] & ZX.CHANNEL_READABLE,
          equals(ZX.CHANNEL_READABLE)); // pending
    });

    test('async wait channel closed', () async {
      final HandlePairResult pair = System.channelCreate();
      final Completer<int> completer = Completer<int>();
      pair.first.asyncWait(ZX.CHANNEL_PEER_CLOSED, (int status, int pending) {
        completer.complete(status);
      });

      expect(completer.isCompleted, isFalse);

      pair.second.close();

      final int status = await completer.future;
      expect(status, equals(ZX.OK));
    });
  });

  group('channel etc functions', () {
    test('moved handle', () {
      final HandlePairResult pair = System.channelCreate();
      final ByteData data = utf8Bytes('');
      final HandlePairResult transferred = System.channelCreate();

      final HandleDisposition disposition = HandleDisposition(ZX.HANDLE_OP_MOVE,
          transferred.first, ZX.OBJ_TYPE_CHANNEL, ZX.RIGHTS_IO);
      final int status = System.channelWriteEtc(
          pair.first, data, <HandleDisposition>[disposition]);
      expect(status, equals(ZX.OK));
      expect(disposition.result, equals(ZX.OK));
      expect(transferred.first.isValid, isFalse);

      final ReadEtcResult readResult =
          System.channelQueryAndReadEtc(pair.second);
      expect(readResult.status, equals(ZX.OK));
      expect(readResult.numBytes, equals(0));
      expect(readResult.bytes.lengthInBytes, equals(0));
      expect(readResult.bytesAsUTF8String(), equals(''));
      expect(readResult.handleInfos.length, equals(1));
      final HandleInfo handleInfo = readResult.handleInfos[0];
      expect(handleInfo.handle.isValid, isTrue);
      expect(handleInfo.type, equals(ZX.OBJ_TYPE_CHANNEL));
      expect(handleInfo.rights, equals(ZX.RIGHTS_IO));
    });

    test('copied handle', () {
      final HandlePairResult pair = System.channelCreate();
      final ByteData data = utf8Bytes('');
      final HandleResult vmo = System.vmoCreate(0);

      final HandleDisposition disposition = HandleDisposition(
          ZX.HANDLE_OP_DUPLICATE,
          vmo.handle,
          ZX.OBJ_TYPE_VMO,
          ZX.RIGHT_SAME_RIGHTS);
      final int status = System.channelWriteEtc(
          pair.first, data, <HandleDisposition>[disposition]);
      expect(status, equals(ZX.OK));
      expect(disposition.result, equals(ZX.OK));
      expect(vmo.handle.isValid, isTrue);

      final ReadEtcResult readResult =
          System.channelQueryAndReadEtc(pair.second);
      expect(readResult.status, equals(ZX.OK));
      expect(readResult.numBytes, equals(0));
      expect(readResult.bytes.lengthInBytes, equals(0));
      expect(readResult.bytesAsUTF8String(), equals(''));
      expect(readResult.handleInfos.length, equals(1));
      final HandleInfo handleInfo = readResult.handleInfos[0];
      expect(handleInfo.handle.isValid, isTrue);
      expect(handleInfo.type, equals(ZX.OBJ_TYPE_VMO));
      expect(handleInfo.rights, equals(ZX.DEFAULT_VMO_RIGHTS));
    });

    test('closed handle should error', () {
      final HandlePairResult pair = System.channelCreate();
      final ByteData data = utf8Bytes('');
      final HandlePairResult closed = System.channelCreate();

      final HandleDisposition disposition = HandleDisposition(ZX.HANDLE_OP_MOVE,
          closed.first, ZX.OBJ_TYPE_CHANNEL, ZX.RIGHT_SAME_RIGHTS);
      closed.first.close();
      final int status = System.channelWriteEtc(
          pair.first, data, <HandleDisposition>[disposition]);
      expect(status, equals(ZX.ERR_BAD_HANDLE));
      expect(disposition.result, equals(ZX.ERR_BAD_HANDLE));
      expect(closed.first.isValid, isFalse);

      final ReadEtcResult readResult =
          System.channelQueryAndReadEtc(pair.second);
      expect(readResult.status, equals(ZX.ERR_SHOULD_WAIT));
    });

    test('multiple handles', () {
      final HandlePairResult pair = System.channelCreate();
      final ByteData data = utf8Bytes('');
      final HandlePairResult transferred = System.channelCreate();
      final HandleResult vmo = System.vmoCreate(0);

      final List<HandleDisposition> dispositions = [
        HandleDisposition(ZX.HANDLE_OP_MOVE, transferred.first,
            ZX.OBJ_TYPE_CHANNEL, ZX.RIGHTS_IO),
        HandleDisposition(ZX.HANDLE_OP_DUPLICATE, vmo.handle, ZX.OBJ_TYPE_VMO,
            ZX.RIGHT_SAME_RIGHTS)
      ];
      final int status = System.channelWriteEtc(pair.first, data, dispositions);
      expect(status, equals(ZX.OK));
      expect(dispositions[0].result, equals(ZX.OK));
      expect(dispositions[1].result, equals(ZX.OK));
      expect(transferred.first.isValid, isFalse);
      expect(vmo.handle.isValid, isTrue);

      final ReadEtcResult readResult =
          System.channelQueryAndReadEtc(pair.second);
      expect(readResult.status, equals(ZX.OK));
      expect(readResult.numBytes, equals(0));
      expect(readResult.bytes.lengthInBytes, equals(0));
      expect(readResult.bytesAsUTF8String(), equals(''));

      expect(readResult.handleInfos.length, equals(2));
      final HandleInfo handleInfo = readResult.handleInfos[0];
      expect(handleInfo.handle.isValid, isTrue);
      expect(handleInfo.type, equals(ZX.OBJ_TYPE_CHANNEL));
      expect(handleInfo.rights, equals(ZX.RIGHTS_IO));
      final HandleInfo vmoInfo = readResult.handleInfos[1];
      expect(vmoInfo.handle.isValid, isTrue);
      expect(vmoInfo.type, equals(ZX.OBJ_TYPE_VMO));
      expect(vmoInfo.rights, equals(ZX.DEFAULT_VMO_RIGHTS));
    });
  });

  group('eventpair', () {
    test('create', () {
      final HandlePairResult pair = System.eventpairCreate();
      expect(pair.status, equals(ZX.OK));
      expect(pair.first.isValid, isTrue);
      expect(pair.second.isValid, isTrue);
    });

    test('duplicate', () {
      final HandlePairResult pair = System.eventpairCreate();
      expect(pair.status, equals(ZX.OK));
      expect(pair.first.isValid, isTrue);
      expect(pair.second.isValid, isTrue);

      expect(pair.first.duplicate(ZX.RIGHT_SAME_RIGHTS).isValid, isTrue);
      expect(pair.second.duplicate(ZX.RIGHT_SAME_RIGHTS).isValid, isTrue);
    });

    test('close', () {
      final HandlePairResult pair = System.eventpairCreate();
      expect(pair.first.close(), equals(0));
      expect(pair.first.isValid, isFalse);
      expect(pair.second.isValid, isTrue);

      expect(pair.second.close(), equals(0));
      expect(pair.second.isValid, isFalse);
    });

    test('async wait peer closed', () async {
      final HandlePairResult pair = System.eventpairCreate();
      final Completer<int> completer = Completer<int>();
      pair.first.asyncWait(ZX.EVENTPAIR_PEER_CLOSED, (int status, int pending) {
        completer.complete(status);
      });

      expect(completer.isCompleted, isFalse);
      pair.second.close();

      final int status = await completer.future;
      expect(status, equals(ZX.OK));
    });
  });

  // NOTE: This only tests stream sockets.
  // We should add tests for datagram sockets.
  group('socket', () {
    test('create socket', () {
      final HandlePairResult pair = System.socketCreate();
      expect(pair.status, equals(ZX.OK));
      expect(pair.first.isValid, isTrue);
      expect(pair.second.isValid, isTrue);
    });

    test('close socket', () {
      final HandlePairResult pair = System.socketCreate();
      expect(pair.first.close(), equals(0));
      expect(pair.first.isValid, isFalse);
      expect(pair.second.isValid, isTrue);
      final WriteResult firstResult =
          System.socketWrite(pair.first, ByteData(1), 0);
      expect(firstResult.status, equals(ZX.ERR_BAD_HANDLE));
      final WriteResult secondResult =
          System.socketWrite(pair.second, ByteData(1), 0);
      expect(secondResult.status, equals(ZX.ERR_PEER_CLOSED));
    });

    test('read write socket', () {
      final HandlePairResult pair = System.socketCreate();

      // When no data is available, ZX.ERR_SHOULD_WAIT is returned.
      expect(
          System.socketRead(pair.second, 1).status, equals(ZX.ERR_SHOULD_WAIT));

      final ByteData data = utf8Bytes('Hello, world');
      final WriteResult writeResult = System.socketWrite(pair.first, data, 0);
      expect(writeResult.status, equals(ZX.OK));

      final ReadResult readResult =
          System.socketRead(pair.second, data.lengthInBytes);
      expect(readResult.status, equals(ZX.OK));
      expect(readResult.numBytes, equals(data.lengthInBytes));
      expect(readResult.bytes.lengthInBytes, equals(data.lengthInBytes));
      expect(readResult.bytesAsUTF8String(), equals('Hello, world'));
    });

    test('partial read socket', () {
      final HandlePairResult pair = System.socketCreate();
      final ByteData data = utf8Bytes('Hello, world');
      final WriteResult writeResult = System.socketWrite(pair.first, data, 0);
      expect(writeResult.status, equals(ZX.OK));

      const int shortLength = 'Hello'.length;
      final ReadResult shortReadResult =
          System.socketRead(pair.second, shortLength);
      expect(shortReadResult.status, equals(ZX.OK));
      expect(shortReadResult.numBytes, equals(shortLength));
      expect(shortReadResult.bytes.lengthInBytes, equals(shortLength));
      expect(shortReadResult.bytesAsUTF8String(), equals('Hello'));

      final int longLength = data.lengthInBytes * 2;
      final ReadResult longReadResult =
          System.socketRead(pair.second, longLength);
      expect(longReadResult.status, equals(ZX.OK));
      expect(longReadResult.numBytes, equals(data.lengthInBytes - shortLength));
      expect(longReadResult.bytes.lengthInBytes, equals(longLength));
      expect(longReadResult.bytesAsUTF8String(), equals(', world'));
    });

    test('partial write socket', () {
      final HandlePairResult pair = System.socketCreate();
      final WriteResult writeResult1 =
          System.socketWrite(pair.first, utf8Bytes('Hello, '), 0);
      expect(writeResult1.status, equals(ZX.OK));
      final WriteResult writeResult2 =
          System.socketWrite(pair.first, utf8Bytes('world'), 0);
      expect(writeResult2.status, equals(ZX.OK));

      final ReadResult readResult = System.socketRead(pair.second, 100);
      expect(readResult.status, equals(ZX.OK));
      expect(readResult.numBytes, equals('Hello, world'.length));
      expect(readResult.bytes.lengthInBytes, equals(100));
      expect(readResult.bytesAsUTF8String(), equals('Hello, world'));
    });

    test('async wait socket read', () async {
      final HandlePairResult pair = System.socketCreate();
      final Completer<int> completer = Completer<int>();
      pair.first.asyncWait(ZX.SOCKET_READABLE, (int status, int pending) {
        completer.complete(status);
      });

      expect(completer.isCompleted, isFalse);

      System.socketWrite(pair.second, utf8Bytes('Hi'), 0);

      final int status = await completer.future;
      expect(status, equals(ZX.OK));
    });

    test('async wait socket closed', () async {
      final HandlePairResult pair = System.socketCreate();
      final Completer<int> completer = Completer<int>();
      pair.first.asyncWait(ZX.SOCKET_PEER_CLOSED, (int status, int pending) {
        completer.complete(status);
      });

      expect(completer.isCompleted, isFalse);

      pair.second.close();

      final int status = await completer.future;
      expect(status, equals(ZX.OK));
    });
  });

  group('vmo', () {
    test('fromFile', () {
      const String fuchsia = 'Fuchsia';
      File f = File('tmp/testdata')
        ..createSync()
        ..writeAsStringSync(fuchsia);
      String readFuchsia = f.readAsStringSync();
      expect(readFuchsia, equals(fuchsia));

      FromFileResult fileResult = System.vmoFromFile('tmp/testdata');
      expect(fileResult.status, equals(ZX.OK));
      MapResult mapResult = System.vmoMap(fileResult.handle);
      expect(mapResult.status, equals(ZX.OK));
      Uint8List fileData = mapResult.data.asUnmodifiableView();
      String fileString = utf8.decode(fileData.sublist(0, fileResult.numBytes));
      expect(fileString, equals(fuchsia));
    });

    test('duplicate', () {
      const String fuchsia = 'Fuchsia';
      Uint8List data = Uint8List.fromList(fuchsia.codeUnits);
      HandleResult createResult = System.vmoCreate(data.length);
      expect(createResult.status, equals(ZX.OK));
      int writeResult = System.vmoWrite(createResult.handle, 0,
                                        data.buffer.asByteData());
      expect(writeResult, equals(ZX.OK));
      Handle duplicate = createResult.handle.duplicate(ZX.RIGHTS_BASIC |
                                                       ZX.RIGHT_READ |
                                                       ZX.RIGHT_MAP);
      expect(duplicate.isValid, isTrue);

      // Read from the duplicate.
      MapResult mapResult = System.vmoMap(duplicate);
      expect(mapResult.status, equals(ZX.OK));
      Uint8List vmoData = mapResult.data.asUnmodifiableView();
      String vmoString = utf8.decode(vmoData.sublist(0, data.length));
      expect(vmoString, equals(fuchsia));
    });
  });
}
