File: RTCPeerConnection-setRemoteDescription-rollback.html

package info (click to toggle)
firefox-esr 68.10.0esr-1~deb9u1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 3,143,932 kB
  • sloc: cpp: 5,227,879; javascript: 4,315,531; ansic: 2,467,042; python: 794,975; java: 349,993; asm: 232,034; xml: 228,320; sh: 82,008; lisp: 41,202; makefile: 22,347; perl: 15,555; objc: 5,277; cs: 4,725; yacc: 1,778; ada: 1,681; pascal: 1,673; lex: 1,417; exp: 527; php: 436; ruby: 225; awk: 162; sed: 53; csh: 44
file content (162 lines) | stat: -rw-r--r-- 6,215 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
<!doctype html>
<meta charset=utf-8>
<title>RTCPeerConnection.prototype.setRemoteDescription rollback</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 editor draft:
  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html

  // The following helper functions are called from RTCPeerConnection-helper.js:
  //   assert_session_desc_similar
  //   generateAudioReceiveOnlyOffer
  //   generateDataChannelOffer

  /*
    4.3.2.  Interface Definition
      [Constructor(optional RTCConfiguration configuration)]
      interface RTCPeerConnection : EventTarget {
        Promise<void>                      setLocalDescription(
            RTCSessionDescriptionInit description);

        readonly attribute RTCSessionDescription? localDescription;
        readonly attribute RTCSessionDescription? currentLocalDescription;
        readonly attribute RTCSessionDescription? pendingLocalDescription;

        Promise<void>                      setRemoteDescription(
            RTCSessionDescriptionInit description);

        readonly attribute RTCSessionDescription? remoteDescription;
        readonly attribute RTCSessionDescription? currentRemoteDescription;
        readonly attribute RTCSessionDescription? pendingRemoteDescription;
        ...
      };

    4.6.2.  RTCSessionDescription Class
      dictionary RTCSessionDescriptionInit {
        required RTCSdpType type;
                 DOMString  sdp = "";
      };

    4.6.1.  RTCSdpType
      enum RTCSdpType {
        "offer",
        "pranswer",
        "answer",
        "rollback"
      };
   */

  /*
    4.3.1.6.  Set the RTCSessionSessionDescription
      2.2.3.  Otherwise, if description is set as a remote description, then run one
              of the following steps:
        - If description is of type "rollback", then this is a rollback.
          Set connection.pendingRemoteDescription to null and signaling state to stable.
   */
  promise_test(t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());

    const states = [];
    pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));

    return generateDataChannelOffer(pc)
    .then(offer => pc.setRemoteDescription(offer))
    .then(() => {
      assert_equals(pc.signalingState, 'have-remote-offer');
      assert_not_equals(pc.remoteDescription, null);
      assert_not_equals(pc.pendingRemoteDescription, null);
      assert_equals(pc.currentRemoteDescription, null);

      return pc.setRemoteDescription({ type: 'rollback' });
    })
    .then(() => {
      assert_equals(pc.signalingState, 'stable');
      assert_equals(pc.remoteDescription, null);
      assert_equals(pc.pendingRemoteDescription, null);
      assert_equals(pc.currentRemoteDescription, null);

      assert_array_equals(states, ['have-remote-offer', 'stable']);
    });
  }, 'setRemoteDescription(rollback) in have-remote-offer state should revert to stable state');

  /*
    4.3.1.6.  Set the RTCSessionSessionDescription
      2.3.  If the description's type is invalid for the current signaling state of
            connection, then reject p with a newly created InvalidStateError and abort
            these steps.

    [jsep]
      4.1.8.2.  Rollback
        - Rollback can only be used to cancel proposed changes;
          there is no support for rolling back from a stable state to a
          previous stable state
   */
  promise_test(t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    return promise_rejects(t, 'InvalidStateError',
      pc.setRemoteDescription({ type: 'rollback' }));
  }, `setRemoteDescription(rollback) from stable state should reject with InvalidStateError`);

  promise_test(t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    return generateAudioReceiveOnlyOffer(pc)
    .then(offer => pc.setRemoteDescription(offer))
    .then(() => pc.setRemoteDescription({
      type: 'rollback',
      sdp: '!<Invalid SDP Content>;'
    }));
  }, `setRemoteDescription(rollback) should ignore invalid sdp content and succeed`);

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

    // We don't use this right away
    const offer1 = await pc1.createOffer({offerToReceiveAudio: true});

    // Create offer from pc2, apply and rollback on pc1
    const offer2 = await pc2.createOffer({offerToReceiveAudio: true});
    await pc1.setRemoteDescription(offer2);
    await pc1.setRemoteDescription({type: "rollback"});

    // Then try applying pc1's old offer
    await pc1.setLocalDescription(offer1);
  }, `local offer created before setRemoteDescription(remote offer) then rollback should still be usable`);

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

    const stream = await getNoiseStream({ video: true });
    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
    pc1.addTrack(stream.getTracks()[0], stream);

    // We don't use this right away. pc1 has provisionally decided that the
    // (only) transceiver is bound to level 0.
    const offer1 = await pc1.createOffer();

    // Create offer from pc2, apply and rollback on pc1
    const offer2 = await pc2.createOffer({offerToReceiveAudio: true, offerToReceiveVideo: true});
    // pc1 now should change its mind about what level its video transceiver is
    // bound to. It was 0, now it is 1.
    await pc1.setRemoteDescription(offer2);

    // Rolling back should put things back the way they were.
    await pc1.setRemoteDescription({type: "rollback"});

    // Then try applying pc1's old offer
    await pc1.setLocalDescription(offer1);
  }, "local offer created before setRemoteDescription(remote offer) with different transceiver level assignments then rollback should still be usable");

</script>