<!doctype html>
<meta charset=utf-8>
<title>RTCDataChannel id attribute</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="RTCPeerConnection-helper.js"></script>
<script>
'use strict';

// Test is based on the following revision:
// https://rawgit.com/w3c/webrtc-pc/1cc5bfc3ff18741033d804c4a71f7891242fb5b3/webrtc.html

// This is the maximum number of streams, NOT the maximum stream ID (which is 65534)
// See: https://tools.ietf.org/html/draft-ietf-rtcweb-data-channel-13#section-6.2
const nStreams = 65535;

/*
  6.1.
    21. If the [[DataChannelId]] slot is null (due to no ID being passed into
        createDataChannel, or [[Negotiated]] being false), and the DTLS role of the SCTP
        transport has already been negotiated, then initialize [[DataChannelId]] to a value
        generated by the user agent, according to [RTCWEB-DATA-PROTOCOL] [...]
 */
promise_test(async (t) => {
  const pc = new RTCPeerConnection;
  t.add_cleanup(() => pc.close());

  const dc1 = pc.createDataChannel('');
  const ids = new UniqueSet();

  const offer = await pc.createOffer();
  await pc.setLocalDescription(offer);
  // Turn our own offer SDP into valid answer SDP by setting the DTLS role to
  // "active".
  const answer = {
    type: 'answer',
    sdp: pc.localDescription.sdp.replace('actpass', 'active')
  };
  await pc.setRemoteDescription(answer);

  // Since the remote description had an 'active' DTLS role, we're the server
  // and should use odd data channel IDs, according to rtcweb-data-channel.
  assert_equals(dc1.id % 2, 1,
    `Channel created by the DTLS server role must be odd (was ${dc1.id})`);
  const dc2 = pc.createDataChannel('another');
  assert_equals(dc2.id % 2, 1,
    `Channel created by the DTLS server role must be odd (was ${dc2.id})`);

  // Ensure IDs are unique
  ids.add(dc1.id, `Channel ID ${dc1.id} should be unique`);
  ids.add(dc2.id, `Channel ID ${dc2.id} should be unique`);
}, 'DTLS client uses odd data channel IDs');

promise_test(async (t) => {
  const pc = new RTCPeerConnection;
  t.add_cleanup(() => pc.close());

  const dc1 = pc.createDataChannel('');
  const ids = new UniqueSet();

  const offer = await pc.createOffer();
  await pc.setLocalDescription(offer);
  // Turn our own offer SDP into valid answer SDP by setting the DTLS role to
  // 'passive'.
  const answer = {
    type: 'answer',
    sdp: pc.localDescription.sdp.replace('actpass', 'passive')
  };
  await pc.setRemoteDescription(answer);

  // Since the remote description had a 'passive' DTLS role, we're the client
  // and should use even data channel IDs, according to rtcweb-data-channel.
  assert_equals(dc1.id % 2, 0,
    `Channel created by the DTLS client role must be even (was ${dc1.id})`);
  const dc2 = pc.createDataChannel('another');
  assert_equals(dc2.id % 2, 0,
    `Channel created by the DTLS client role must be even (was ${dc1.id})`);

  // Ensure IDs are unique
  ids.add(dc1.id, `Channel ID ${dc1.id} should be unique`);
  ids.add(dc2.id, `Channel ID ${dc2.id} should be unique`);
}, 'DTLS server uses even data channel IDs');

/*
  Checks that the id is ignored if "negotiated" is false.
  See section 6.1, createDataChannel step 13.
 */
promise_test(async (t) => {
  const pc1 = new RTCPeerConnection();
  const pc2 = new RTCPeerConnection();
  t.add_cleanup(() => pc1.close());
  t.add_cleanup(() => pc2.close());

  const dc1 = pc1.createDataChannel('', {
    negotiated: false,
    id: 42
  });
  dc1.onopen = t.step_func(() => {
    dc1.send(':(');
  });

  const dc2 = pc2.createDataChannel('', {
    negotiated: false,
    id: 42
  });
  // ID should be null prior to negotiation.
  assert_equals(dc1.id, null);
  assert_equals(dc2.id, null);

  exchangeIceCandidates(pc1, pc2);
  await exchangeOfferAnswer(pc1, pc2);
  // We should now have 2 datachannels with different IDs.
  // At least one of the datachannels should not be 42.
  // If one has the value 42, it's an accident; if both have,
  // they are the same datachannel, and it's a bug.
  assert_false(dc1.id == 42 && dc2.id == 42);
}, 'In-band negotiation with a specific ID should not work');

/*
  Check if the implementation still follows the odd/even role correctly if we annoy it with
  negotiated channels not following that rule.

  Note: This test assumes that the implementation can handle a minimum of 40 data channels.
 */
promise_test(async (t) => {
  // Takes the DTLS server role
  const pc1 = new RTCPeerConnection();
  // Takes the DTLS client role
  const pc2 = new RTCPeerConnection();
  t.add_cleanup(() => pc1.close());
  t.add_cleanup(() => pc2.close());

  exchangeIceCandidates(pc1, pc2);
  const dcs = [];
  const negotiatedDcs = [];
  const ids = new UniqueSet();

  // Create 10 DCEP-negotiated channels with pc1
  // Note: These should not have any associated valid ID at this point
  for (let i = 0; i < 10; ++i) {
    const dc = pc1.createDataChannel('before-connection');
    assert_equals(dc.id, null, 'Channel id must be null before DTLS role has been determined');
    dcs.push(dc);
  }

  // Create 10 negotiated channels with pc1 violating the odd/even rule
  for (let id = 0; id < 20; id += 2) {
    const dc = pc1.createDataChannel(`negotiated-not-odd-${id}-before-connection`, {
      negotiated: true,
      id: id,
    });
    assert_equals(dc.id, id, 'Channel id must be set before DTLS role has been determined when negotiated is true');
    negotiatedDcs.push([dc, id]);
    ids.add(dc.id, `Channel ID ${dc.id} should be unique`);
  }

  await exchangeOfferAnswer(pc1, pc2, {
    offer: (offer) => {
      // Ensure pc1 takes the server role
      assert_true(offer.sdp.includes('actpass') || offer.sdp.includes('passive'),
        'pc1 must take the DTLS server role');
      return offer;
    },
    answer: (answer) => {
      // Ensure pc2 takes the client role
      // Note: It very likely will choose 'active' itself
      answer.sdp = answer.sdp.replace('actpass', 'active');
      assert_true(answer.sdp.includes('active'), 'pc2 must take the DTLS client role');
      return answer;
    },
  });

  for (const dc of dcs) {
    assert_equals(dc.id % 2, 1,
      `Channel created by the DTLS server role must be odd (was ${dc.id})`);
    ids.add(dc.id, `Channel ID ${dc.id} should be unique`);
  }

  // Create 10 channels with pc1
  for (let i = 0; i < 10; ++i) {
    const dc = pc1.createDataChannel('after-connection');
    assert_equals(dc.id % 2, 1,
      `Channel created by the DTLS server role must be odd (was ${dc.id})`);
    dcs.push(dc);
    ids.add(dc.id, `Channel ID ${dc.id} should be unique`);
  }

  // Create 10 negotiated channels with pc1 violating the odd/even rule
  for (let i = 0; i < 10; ++i) {
    // Generate a valid even ID that has not been taken, yet.
    let id = 20;
    while (ids.has(id)) {
      id += 2;
    }
    const dc = pc1.createDataChannel(`negotiated-not-odd-${i}-after-connection`, {
      negotiated: true,
      id: id,
    });
    negotiatedDcs.push([dc, id]);
    ids.add(dc.id, `Channel ID ${dc.id} should be unique`);
  }

  // Since we've added new channels, let's check again that the odd/even role is not violated
  for (const dc of dcs) {
    assert_equals(dc.id % 2, 1,
      `Channel created by the DTLS server role must be odd (was ${dc.id})`);
  }

  // Let's also make sure the negotiated channels have kept their ID
  for (const [dc, id] of negotiatedDcs) {
    assert_equals(dc.id, id, 'Negotiated channels should keep their assigned ID');
  }
}, 'Odd/even role should not be violated when mixing with negotiated channels');

/*
  Create 32768 (client), 32767 (server) channels to make sure all ids are exhausted AFTER
  establishing a peer connection.

  6.1.  createDataChannel
    21. If the [[DataChannelId]] slot is null (due to no ID being passed into
        createDataChannel, or [[Negotiated]] being false), and the DTLS role of the SCTP
        transport has already been negotiated, then initialize [[DataChannelId]] to a value
        generated by the user agent, according to [RTCWEB-DATA-PROTOCOL], and skip
        to the next step. If no available ID could be generated, or if the value of the
        [[DataChannelId]] slot is being used by an existing RTCDataChannel, throw an
        OperationError exception.
 */
/*
 TODO: Improve test coverage for RTCSctpTransport.maxChannels.
 TODO: Improve test coverage for exhausting channel cases.
 */

/*
  Create 32768 (client), 32767 (server) channels to make sure all ids are exhausted BEFORE
  establishing a peer connection.

  Be aware that late channel id assignment can currently fail in many places not covered by the
  spec, see: https://github.com/w3c/webrtc-pc/issues/1818

  4.4.1.6.
    2.2.6.  If description negotiates the DTLS role of the SCTP transport, and there is an
            RTCDataChannel with a null id, then generate an ID according to [RTCWEB-DATA-PROTOCOL].
            If no available ID could be generated, then run the following steps:
      1.    Let channel be the RTCDataChannel object for which an ID could not be generated.
      2.    Set channel's [[ReadyState]] slot to "closed".
      3.    Fire an event named error with an OperationError exception at channel.
      4.    Fire a simple event named close at channel.
 */
/* TEST DISABLED - it takes so long, it times out.
promise_test(async (t) => {
  const resolver = new Resolver();
  // Takes the DTLS server role
  const pc1 = new RTCPeerConnection();
  // Takes the DTLS client role
  const pc2 = new RTCPeerConnection();
  t.add_cleanup(() => pc1.close());
  t.add_cleanup(() => pc2.close());

  exchangeIceCandidates(pc1, pc2);
  const dcs = [];
  const ids = new UniqueSet();
  let nExpected = 0;
  let nActualCloses = 0;
  let nActualErrors = 0;

  const maybeDone = t.step_func(() => {
    if (nExpected === nActualCloses && nExpected === nActualErrors) {
      resolver.resolve();
    }
  });

  // Create 65535+2 channels (since 65535 streams is a SHOULD, we may have less than that.)
  // Create two extra channels to possibly trigger the steps in the description.
  //
  // Note: Following the spec strictly would assume that this cannot fail. But in reality it will
  //       fail because the implementation knows how many streams it supports. What it doesn't
  //       know is how many streams the other peer supports (e.g. what will be negotiated).
  for (let i = 0; i < (nStreams + 2); ++i) {
    let dc;
    try {
      const pc = i % 2 === 1 ? pc1 : pc2;
      dc = pc.createDataChannel('this is going to be fun');
      dc.onclose = t.step_func(() => {
        ++nActualCloses;
        maybeDone();
      });
      dc.onerror = t.step_func((e) => {
        assert_true(e instanceof RTCError, 'Expect error object to be instance of RTCError');
        assert_equals(e.error, 'sctp-failure', "Expect error to be of type 'sctp-failure'");
        ++nActualErrors;
        maybeDone();
      });
    } catch (e) {
      assert_equals(e.name, 'OperationError', 'Fail on creation should throw OperationError');
      break;
    }
    assert_equals(dc.id, null, 'Channel id must be null before DTLS role has been determined');
    assert_not_equals(dc.readyState, 'closed',
      'Channel may not be closed before connection establishment');
    dcs.push([dc, i % 2 === 1]);
  }

  await exchangeOfferAnswer(pc1, pc2, {
    offer: (offer) => {
      // Ensure pc1 takes the server role
      assert_true(offer.sdp.includes('actpass') || offer.sdp.includes('passive'),
        'pc1 must take the DTLS server role');
      return offer;
    },
    answer: (answer) => {
      // Ensure pc2 takes the client role
      // Note: It very likely will choose 'active' itself
      answer.sdp = answer.sdp.replace('actpass', 'active');
      assert_true(answer.sdp.includes('active'), 'pc2 must take the DTLS client role');
      return answer;
    },
  });

  // Since the spec does not define a specific order to which channels may fail if an ID could
  // not be generated, any of the channels may be affected by the steps of the description.
  for (const [dc, odd] of dcs) {
    if (dc.readyState !== 'closed') {
      assert_equals(dc.id % 2, odd ? 1 : 0,
        `Channels created by the DTLS ${odd ? 'server' : 'client'} role must be
        ${odd ? 'odd' : 'even'} (was ${dc.id})`);
      ids.add(dc.id, `Channel ID ${dc.id} should be unique`);
    } else {
      ++nExpected;
    }
  }

  // Try creating one further channel on both sides. The attempt should fail since all IDs are
  // taken. If one ID is available, the implementation probably miscounts (or I did in the test).
  assert_throws_dom('OperationError', () =>
    pc1.createDataChannel('this is too exhausting!'));
  assert_throws_dom('OperationError', () =>
    pc2.createDataChannel('this is too exhausting!'));

  maybeDone();
  await resolver;
}, 'Channel ID exhaustion handling (before and after connection establishment)');

END DISABLED TEST */

</script>
