我编写了两个单元测试来验证我的应用程序中是否正确实现了提供/应答机制。第一个单元测试在收到商品时验证对等体的行为,而第二个单元测试在创建商品时验证对等体的行为。对于我的单元测试,我使用了以下模拟报价和模拟答案:
优惠:
var mockOffer { "sdp": "v=0\r\n" +
"o=- 7282588543017546346 2 IN IP4 127.0.0.1\r\n" +
"s=-\r\n" +
"t=0 0\r\n" +
"a=group:BUNDLE audio video\r\n" +
"a=msid-semantic: WMS\r\n" +
"m=audio 1 RTP/SAVPF 111 103 104 0 8 106 105 13 126\r\n" +
"c=IN IP4 0.0.0.0\r\n" +
"a=rtcp:1 IN IP4 0.0.0.0\r\n" +
"a=ice-ufrag:IJU9DHoiy8+X8FtX\r\n" +
"a=ice-pwd:3qgT9ydEM/CMkgan8ZWvgvbg\r\n" +
"a=ice-options:google-ice\r\n" +
"a=fingerprint:sha-256 54:90:7A:6F:BC:46:C4:5F:25:B9:02:97:3D:A7:53:5D:B4:F6:CE:55:EB:78:51:84:0C:41:0B:2B:21:AA:CD:05\r\n" +
"a=setup:actpass\r\n" +
"a=mid:audio\r\n" +
"a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n" +
"a=recvonly\r\n" +
"a=rtcp-mux\r\n" +
"a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:gC/fmSmErYS1MaaCQnXZRtKR6l8yWMc5zbOpdVT8\r\n" +
"a=rtpmap:111 opus/48000/2\r\n" +
"a=fmtp:111 minptime=10\r\n" +
"a=rtpmap:103 ISAC/16000\r\n" +
"a=rtpmap:104 ISAC/32000\r\n" +
"a=rtpmap:0 PCMU/8000\r\n" +
"a=rtpmap:8 PCMA/8000\r\n" +
"a=rtpmap:106 CN/32000\r\n" +
"a=rtpmap:105 CN/16000\r\n" +
"a=rtpmap:13 CN/8000\r\n" +
"a=rtpmap:126 telephone-event/8000\r\n" +
"a=maxptime:60\r\n" +
"m=video 1 RTP/SAVPF 100 116 117\r\n" +
"c=IN IP4 0.0.0.0\r\n" +
"a=rtcp:1 IN IP4 0.0.0.0\r\n" +
"a=ice-ufrag:IJU9DHoiy8+X8FtX\r\n" +
"a=ice-pwd:3qgT9ydEM/CMkgan8ZWvgvbg\r\n" +
"a=ice-options:google-ice\r\n" +
"a=fingerprint:sha-256 54:90:7A:6F:BC:46:C4:5F:25:B9:02:97:3D:A7:53:5D:B4:F6:CE:55:EB:78:51:84:0C:41:0B:2B:21:AA:CD:05\r\n" +
"a=setup:actpass\r\n" +
"a=mid:video\r\n" +
"a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\r\n" +
"a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n" +
"a=recvonly\r\n" +
"a=rtcp-mux\r\n" +
"a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:gC/fmSmErYS1MaaCQnXZRtKR6l8yWMc5zbOpdVT8\r\n" +
"a=rtpmap:100 VP8/90000\r\n" +
"a=rtcp-fb:100 ccm fir\r\n" +
"a=rtcp-fb:100 nack\r\n" +
"a=rtcp-fb:100 nack pli\r\n" +
"a=rtcp-fb:100 goog-remb\r\n" +
"a=rtpmap:116 red/90000\r\n" +
"a=rtpmap:117 ulpfec/90000\r\n",
"type":"offer"};
答案:
var mockAnswer = {"sdp":
"v=0\r\n" +
"o=- 6465573306213105510 2 IN IP4 127.0.0.1\r\n" +
"s=-\r\n" +
"t=0 0\r\n" +
"a=group:BUNDLE audio video\r\n" +
"a=msid-semantic: WMS\r\n" +
"m=audio 1 RTP/SAVPF 111 103 104 0 8 106 105 13 126\r\n" +
"c=IN IP4 0.0.0.0\r\n" +
"a=rtcp:1 IN IP4 0.0.0.0\r\n" +
"a=ice-ufrag:AyBahFUhrQOPtHlQ\r\n" +
"a=ice-pwd:QGUAtvpJDqYq2F8BUH2ZWdGv\r\n" +
"a=fingerprint:sha-256 54:90:7A:6F:BC:46:C4:5F:25:B9:02:97:3D:A7:53:5D:B4:F6:CE:55:EB:78:51:84:0C:41:0B:2B:21:AA:CD:05\r\n" +
"a=setup:active\r\n" +
"a=mid:audio\r\n" +
"a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n" +
"a=sendonly\r\n" +
"a=rtcp-mux\r\n" +
"a=rtpmap:111 opus/48000/2\r\n" +
"a=fmtp:111 minptime=10\r\n" +
"a=rtpmap:103 ISAC/16000\r\n" +
"a=rtpmap:104 ISAC/32000\r\n" +
"a=rtpmap:0 PCMU/8000\r\n" +
"a=rtpmap:8 PCMA/8000\r\n" +
"a=rtpmap:106 CN/32000\r\n" +
"a=rtpmap:105 CN/16000\r\n" +
"a=rtpmap:13 CN/8000\r\n" +
"a=rtpmap:126 telephone-event/8000\r\n" +
"a=maxptime:60\r\n" +
"m=video 1 RTP/SAVPF 100 116 117\r\n" +
"c=IN IP4 0.0.0.0\r\n" +
"a=rtcp:1 IN IP4 0.0.0.0\r\n" +
"a=ice-ufrag:AyBahFUhrQOPtHlQ\r\n" +
"a=ice-pwd:QGUAtvpJDqYq2F8BUH2ZWdGv\r\n" +
"a=fingerprint:sha-256 54:90:7A:6F:BC:46:C4:5F:25:B9:02:97:3D:A7:53:5D:B4:F6:CE:55:EB:78:51:84:0C:41:0B:2B:21:AA:CD:05\r\n" +
"a=setup:active\r\n" +
"a=mid:video\r\n" +
"a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\r\n" +
"a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n" +
"a=sendonly\r\n" +
"a=rtcp-mux\r\n" +
"a=rtpmap:100 VP8/90000\r\n" +
"a=rtcp-fb:100 ccm fir\r\n" +
"a=rtcp-fb:100 nack\r\n" +
"a=rtcp-fb:100 nack pli\r\n" +
"a=rtcp-fb:100 goog-remb\r\n" +
"a=rtpmap:116 red/90000\r\n" +
"a=rtpmap:117 ulpfec/90000\r\n",
"type": "answer"};
注意:它们是使用createAnswer和createOffer方法生成的。
当对等方收到远程服务并回复答案时,第一个单元测试将镜像该方案。我用提议调用setRemoteDescriptor,然后我给serLocalDescriptor调用了答案。此测试工作正常,不会抛出任何错误,并且SignallingState根据执行的操作而更改(即setRemoteDescriptor导致SignalingState更改has-remote-offer,依此类推......)。
单元测试:
it("Test the signalStatus machine when a peer receives an offer", function(done){
var peerReceiver = new app.PeerConnection("mock_receiver", session, false);
var successRemote = function(){
console.log("Remote descriptor installed successfully.");
expect(peerReceiver.getSignalingState()).toEqual("have-remote-offer");
peerReceiver._setLocalDescriptor(mockAnswer, successLocal, failure);
};
var successLocal = function(){
console.log("Local descriptor installed successfully.");
expect(peerReceiver.getSignalingState()).toEqual("stable");
done();
}.bind(this);
var failure = function(error){
console.log("Error installing SDP." + error);
expect(error).toBeNull();
done();
}.bind(this);
expect(peerReceiver.getSignalingState()).toEqual("none");
peerReceiver._setRemoteDescription(mockOffer, successRemote,failure);
});
第二个单元测试使用相同的模拟答案和提议,但它反映了对等方创建和设置本地商品并将远程对等方收到的答案设置为远程服务时的方案。 测试使用offer调用setLocalDescriptor。因此,SIngnalingState更改为have-local-offer。然后使用mockAnswer调用setRemoteDescription。此调用会生成以下错误:
ERROR : Failed to set remote answer sdp: Failed to push down transport description: Failed to apply remote fingerprint.
可能是什么原因?难道我做错了什么?报价和答案中的指纹完全相同,如果指纹出现问题,第一次单元测试中也应该出现问题。我很无能为力。任何建议,建议都是受欢迎的。 :D
单元测试失败:
it("Test the signalStatus machine when a peer sends an offer", function(done){
var peerSender = new app.PeerConnection("mock_sender", session, false);
var successRemote = function(){
console.log("Remote descriptor installed successfully.");
expect(peerSender.getSignalingState()).toEqual("stable");
done();
};
var successLocal = function(){
console.log("Local descriptor installed successfully.");
expect(peerSender.getSignalingState()).toEqual("have-local-offer");
peerSender._setRemoteDescription(mockAnswer, successRemote,failure);
}.bind(this);
var failure = function(error){
console.log("Error installing SDP." + error);
expect(error).toBeNull();
done();
}.bind(this);
expect(peerSender.getSignalingState()).toEqual("none");
peerSender._setLocalDescriptor(mockOffer, successLocal,failure);
});
RPCPeerConnection对象,生成错误时:
RTCPeerConnection {ondatachannel: null, oniceconnectionstatechange: function, onremovestream: function, onaddstream: function, onsignalingstatechange: function…}
iceConnectionState: "new"
iceGatheringState: "new"
localDescription: RTCSessionDescription
onaddstream: function (stream) { self.onRemoteStreamAdded(stream);}
ondatachannel: null
onicecandidate: function (e) { self.onIceCandidate(e, pc.iceGatheringState)}
oniceconnectionstatechange: function (e) { self.onIceConnectionStatusStateChange(e)}
onnegotiationneeded: null
onremovestream: function (stream) { self.onRemoteStreamRemoved(stream);}
onsignalingstatechange: function (e) {self.onSignalingStateChange(e)}
remoteDescription: null
signalingState: "have-local-offer"
__proto__: RTCPeerConnection
PeerConnection.js:287
Error installing SDP.undefined
可以找到整个源代码here
如果您需要更多信息,请与我们联系。