def parseJob(self, f): # jobfiles are serialized build requests. Each is a list of # serialized netstrings, in the following order: # "2", the format version number ("1" does not have project/repo) # buildsetID, arbitrary string, used to find the buildSet later # branch name, "" for default-branch # base revision, "" for HEAD # patchlevel, usually "1" # patch # builderNames... p = netstrings.NetstringParser() try: p.feed(f.read()) except basic.NetstringParseError: raise BadJobfile("unable to parse netstrings") if not p.strings: raise BadJobfile("could not find any complete netstrings") ver = p.strings.pop(0) if ver == "1": buildsetID, branch, baserev, patchlevel, diff = p.strings[:5] builderNames = p.strings[5:] if branch == "": branch = None if baserev == "": baserev = None patchlevel = int(patchlevel) repository = '' project = '' who = '' elif ver == "2": # introduced the repository and project property buildsetID, branch, baserev, patchlevel, diff, repository, project = p.strings[: 7] builderNames = p.strings[7:] if branch == "": branch = None if baserev == "": baserev = None patchlevel = int(patchlevel) who = '' elif ver == "3": # introduced who property buildsetID, branch, baserev, patchlevel, diff, repository, project, who = p.strings[: 8] builderNames = p.strings[8:] if branch == "": branch = None if baserev == "": baserev = None patchlevel = int(patchlevel) else: raise BadJobfile("unknown version '%s'" % ver) return dict(builderNames=builderNames, branch=branch, baserev=baserev, patch_body=diff, patch_level=patchlevel, repository=repository, project=project, who=who, jobid=buildsetID)
def parseJob(self, f): # jobfiles are serialized build requests. Each is a list of # serialized netstrings, in the following order: # format version number: # "1" the original # "2" introduces project and repository # "3" introduces who # "4" introduces comment # "5" introduces properties and JSON serialization of values after # version # jobid: arbitrary string, used to find the buildSet later # branch: branch name, "" for default-branch # baserev: revision, "" for HEAD # patch_level: usually "1" # patch_body: patch to be applied for build # repository # project # who: user requesting build # comment: comment from user about diff and/or build # builderNames: list of builder names # properties: dict of build properties p = netstrings.NetstringParser() f.seek(0, 2) if f.tell() > basic.NetstringReceiver.MAX_LENGTH: raise BadJobfile( "The patch size is greater that NetStringReceiver.MAX_LENGTH. Please Set this higher in the master.cfg" ) f.seek(0, 0) try: p.feed(f.read()) except basic.NetstringParseError: raise BadJobfile("unable to parse netstrings") if not p.strings: raise BadJobfile("could not find any complete netstrings") ver = p.strings.pop(0) v1_keys = ['jobid', 'branch', 'baserev', 'patch_level', 'patch_body'] v2_keys = v1_keys + ['repository', 'project'] v3_keys = v2_keys + ['who'] v4_keys = v3_keys + ['comment'] keys = [v1_keys, v2_keys, v3_keys, v4_keys] # v5 introduces properties and uses JSON serialization parsed_job = {} def extract_netstrings(p, keys): for i, key in enumerate(keys): parsed_job[key] = p.strings[i] def postprocess_parsed_job(): # apply defaults and handle type casting parsed_job['branch'] = parsed_job['branch'] or None parsed_job['baserev'] = parsed_job['baserev'] or None parsed_job['patch_level'] = int(parsed_job['patch_level']) for key in 'repository project who comment'.split(): parsed_job[key] = parsed_job.get(key, '') parsed_job['properties'] = parsed_job.get('properties', {}) if ver <= "4": i = int(ver) - 1 extract_netstrings(p, keys[i]) parsed_job['builderNames'] = p.strings[len(keys[i]):] postprocess_parsed_job() elif ver == "5": try: parsed_job = json.loads(p.strings[0]) except ValueError: raise BadJobfile("unable to parse JSON") postprocess_parsed_job() else: raise BadJobfile("unknown version '%s'" % ver) return parsed_job
def test_incomplete_netstring(self): p = netstrings.NetstringParser() p.feed("11:hello world,6:foob") # note that the incomplete 'foobar' does not appear here self.assertEqual(p.strings, ['hello world'])
def test_invalid_netstring(self): p = netstrings.NetstringParser() self.assertRaises(basic.NetstringParseError, lambda: p.feed("5-hello!"))
def test_valid_netstrings_byte_by_byte(self): # (this is really testing twisted's support, but oh well) p = netstrings.NetstringParser() [p.feed(c) for c in "5:hello,5:world,"] self.assertEqual(p.strings, ['hello', 'world'])
def test_valid_netstrings(self): p = netstrings.NetstringParser() p.feed("5:hello,5:world,") self.assertEqual(p.strings, ['hello', 'world'])