From 69d46b4821860c434637b32cf481045e8980bca4 Mon Sep 17 00:00:00 2001 From: "phoglund@webrtc.org" Date: Mon, 24 Sep 2012 07:44:02 +0000 Subject: [PATCH] Added basic fuzzer for new API and made both work. Added a nice mode, cleaned up. BUG= Review URL: https://webrtc-codereview.appspot.com/832004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2807 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../corpus/{template.html => template00.html} | 26 ++-- .../peerconnection/corpus/template01.html | 124 ++++++++++++++++++ src/test/fuzz/peerconnection/fuzz_main_run.py | 48 ++++++- .../peerconnection/peerconnection_fuzz.py | 26 +++- 4 files changed, 204 insertions(+), 20 deletions(-) rename src/test/fuzz/peerconnection/corpus/{template.html => template00.html} (84%) create mode 100644 src/test/fuzz/peerconnection/corpus/template01.html diff --git a/src/test/fuzz/peerconnection/corpus/template.html b/src/test/fuzz/peerconnection/corpus/template00.html similarity index 84% rename from src/test/fuzz/peerconnection/corpus/template.html rename to src/test/fuzz/peerconnection/corpus/template00.html index 5cb8e2dfe..2856d1a7e 100644 --- a/src/test/fuzz/peerconnection/corpus/template.html +++ b/src/test/fuzz/peerconnection/corpus/template00.html @@ -41,24 +41,24 @@ INCLUDE_FUZZ_SDP_JS return offer.toSdp(); } - function receiveCall(offer_sdp) { + function receiveCall(offerSdp) { gSecondConnection = new webkitPeerConnection00( null, onIceCandidateToSecond); gSecondConnection.onaddstream = onRemoteStream; - var parsed_offer = new SessionDescription(offer_sdp); + var parsedOffer = new SessionDescription(offerSdp); gSecondConnection.setRemoteDescription( - webkitPeerConnection00.SDP_OFFER, parsed_offer); + webkitPeerConnection00.SDP_OFFER, parsedOffer); var answer = gSecondConnection.createAnswer( - offer_sdp, { has_audio: true, has_video: true }); + offerSdp, { has_audio: true, has_video: true }); gSecondConnection.setLocalDescription( webkitPeerConnection00.SDP_ANSWER, answer); gSecondConnection.startIce(); return answer.toSdp(); } - function handleAnswer(answer_sdp) { - var parsed_answer = new SessionDescription(answer_sdp); + function handleAnswer(answerSdp) { + var parsed_answer = new SessionDescription(answerSdp); gFirstConnection.setRemoteDescription( webkitPeerConnection00.SDP_ANSWER, parsed_answer); gFirstConnection.startIce(); @@ -68,13 +68,13 @@ INCLUDE_FUZZ_SDP_JS var localStreamUrl = webkitURL.createObjectURL(localStream); document.getElementById('local-view').src = localStreamUrl; - var offer_sdp = callUsingStream(localStream); - offer_sdp = gTransformOfferSdp(offer_sdp); - var answer_sdp = receiveCall(offer_sdp); - answer_sdp = gTransformAnswerSdp(answer_sdp); - console.log(offer_sdp); - console.log(answer_sdp); - handleAnswer(answer_sdp); + var offerSdp = callUsingStream(localStream); + offerSdp = gTransformOfferSdp(offerSdp); + var answerSdp = receiveCall(offerSdp); + answerSdp = gTransformAnswerSdp(answerSdp); + console.log(offerSdp); + console.log(answerSdp); + handleAnswer(answerSdp); } function onIceCandidateToFirst(candidate, more) { diff --git a/src/test/fuzz/peerconnection/corpus/template01.html b/src/test/fuzz/peerconnection/corpus/template01.html new file mode 100644 index 000000000..118695458 --- /dev/null +++ b/src/test/fuzz/peerconnection/corpus/template01.html @@ -0,0 +1,124 @@ + + + + + WebRTC PeerConnection Fuzz Test Template +INCLUDE_RANDOM_JS +INCLUDE_FUZZ_SDP_JS + + + + + + + + + + + + +
Local PreviewRemote Stream
+ + \ No newline at end of file diff --git a/src/test/fuzz/peerconnection/fuzz_main_run.py b/src/test/fuzz/peerconnection/fuzz_main_run.py index 86b3e6238..2f5e1d3d8 100755 --- a/src/test/fuzz/peerconnection/fuzz_main_run.py +++ b/src/test/fuzz/peerconnection/fuzz_main_run.py @@ -7,11 +7,27 @@ # in the file PATENTS. All contributing project authors may # be found in the AUTHORS file in the root of the source tree. -# Based on the ClusterFuzz simple fuzzer template. +"""Fuzzer for peerconnection. +Based on the ClusterFuzz simple fuzzer template. + +I generally use it like this when developing: + +./src/test/fuzz/peerconnection/fuzz_main_run.py --no_of_files=1 \ + --output_dir=. --input_dir=src/test/fuzz/peerconnection/corpus/; \ + cat fuzz-*; mv fuzz-* /home/phoglund/www/fuzz/fuzz.html; \ + cp src/test/fuzz/peerconnection/corpus/* /home/phoglund/www/fuzz/; \ + chmod a+r /home/phoglund/www/fuzz/ + +Add the --be_nice flag to the fuzzer to generate a page that should be able +to set up a call. If a --be_nice-generated page doesn't get a call up, the +code doesn't work with whatever version of the WebRTC spec your current version +of Chrome implements. +""" import getopt import os +import random import sys import tempfile import time @@ -42,14 +58,32 @@ def _IncludeJsFile(js_include_to_replace, js_path, file_data): return FillInParameter(js_include_to_replace, js_file_data, file_data) -def GenerateData(): +def GenerateData(be_nice): + """Generates a html page from the template, with or without fuzzing. + + Args: + be_nice: If true, we won't fuzz the data but rather produce a complete + standard-compliant file. + + Returns: + A tuple (file_data, file_extension). + """ this_scripts_path = os.path.dirname(os.path.realpath(__file__)) corpus_path = os.path.join(this_scripts_path, 'corpus'); - template = _ReadFile(os.path.join(corpus_path, 'template.html')) + # Choose the newest version of the API more often than the old one. + if random.random() < 0.8: + template_to_use = 'template01.html' + else: + template_to_use = 'template00.html' + template = _ReadFile(os.path.join(corpus_path, template_to_use)) file_extension = 'html' - file_data = peerconnection_fuzz.Fuzz(template) + + if be_nice: + file_data = peerconnection_fuzz.MakeWorkingFile(template) + else: + file_data = peerconnection_fuzz.Fuzz(template) # Paste the javascript code in directly since it's hard to make javascript # includes work without data bundles. @@ -69,18 +103,20 @@ if __name__ == '__main__': no_of_files = None input_dir = None output_dir = None + be_nice = False optlist, args = getopt.getopt(sys.argv[1:], '', \ - ['no_of_files=', 'output_dir=', 'input_dir=']) + ['no_of_files=', 'output_dir=', 'input_dir=', 'be_nice']) for option, value in optlist: if option == '--no_of_files': no_of_files = int(value) elif option == '--output_dir': output_dir = value elif option == '--input_dir': input_dir = value + elif option == '--be_nice': be_nice = True assert no_of_files is not None, 'Missing "--no_of_files" argument' assert output_dir is not None, 'Missing "--output_dir" argument' assert input_dir is not None, 'Missing "--input_dir" argument' for file_no in range(no_of_files): - file_data, file_extension = GenerateData() + file_data, file_extension = GenerateData(be_nice) file_data = file_data.encode('utf-8') file_descriptor, file_path = tempfile.mkstemp( prefix='fuzz-http-%d-%d' % (start_time, file_no), diff --git a/src/test/fuzz/peerconnection/peerconnection_fuzz.py b/src/test/fuzz/peerconnection/peerconnection_fuzz.py index a638f821a..3f5d6b065 100644 --- a/src/test/fuzz/peerconnection/peerconnection_fuzz.py +++ b/src/test/fuzz/peerconnection/peerconnection_fuzz.py @@ -57,6 +57,7 @@ def _RandomSdpTransform(): def Fuzz(file_data): + """Fuzzes the passed in template.""" file_data = file_data.decode('utf-8') # Generate a bunch of random numbers and encode them into the page. Since the @@ -74,4 +75,27 @@ def Fuzz(file_data): _RandomSdpTransform(), file_data) - return file_data \ No newline at end of file + return file_data + + +def MakeWorkingFile(file_data): + """Fills in arguments to make a basic working file. + + Used for ensuring that the basic template is standards-compliant. + """ + file_data = file_data.decode('utf-8') + + file_data = FillInParameter('ARRAY_OF_RANDOM_ROLLS', + _ArrayOfRandomRolls(500), + file_data) + file_data = FillInParameter('REQUEST_AUDIO_AND_VIDEO', + '{ video: true, audio: true }', + file_data) + file_data = FillInParameter('TRANSFORM_OFFER_SDP', + _ReturnFirstArgument(), + file_data) + file_data = FillInParameter('TRANSFORM_ANSWER_SDP', + _ReturnFirstArgument(), + file_data) + + return file_data