Provide more info for bsdiff/imgdiff exceptions.

When bsdiff/imgdiff fails, dump the output along with the src/tgt
filenames and block ranges. Also, exit the script gracefully instead
of raising an exception about iterating over 'NoneType'.

Bug: 31381530
Test: Package generates successfully for angler, and error outputs
      correctly with error injection.

Change-Id: I06a2dfe545fbdff7043de05fee34b378453a9291
This commit is contained in:
Tianjie Xu
2016-10-28 17:55:53 -07:00
parent 77dab1ed35
commit b59c17fc8f

View File

@@ -36,23 +36,21 @@ __all__ = ["EmptyImage", "DataImage", "BlockImageDiff"]
def compute_patch(srcfile, tgtfile, imgdiff=False): def compute_patch(srcfile, tgtfile, imgdiff=False):
patchfile = common.MakeTempFile(prefix="patch-") patchfile = common.MakeTempFile(prefix='patch-')
if imgdiff: cmd = ['imgdiff', '-z'] if imgdiff else ['bsdiff']
p = subprocess.call( cmd.extend([srcfile, tgtfile, patchfile])
["imgdiff", "-z", srcfile, tgtfile, patchfile],
stdout=open(os.devnull, 'w'),
stderr=subprocess.STDOUT)
else:
p = subprocess.call(
["bsdiff", srcfile, tgtfile, patchfile],
stdout=open(os.devnull, 'w'),
stderr=subprocess.STDOUT)
if p: # Not using common.Run(), which would otherwise dump all the bsdiff/imgdiff
raise ValueError("diff failed: " + str(p)) # commands when OPTIONS.verbose is True - not useful for the case here, since
# they contain temp filenames only.
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output, _ = p.communicate()
with open(patchfile, "rb") as f: if p.returncode != 0:
raise ValueError(output)
with open(patchfile, 'rb') as f:
return f.read() return f.read()
@@ -718,6 +716,7 @@ class BlockImageDiff(object):
diff_total = len(diff_queue) diff_total = len(diff_queue)
patches = [None] * diff_total patches = [None] * diff_total
error_messages = []
if sys.stdout.isatty(): if sys.stdout.isatty():
global diff_done global diff_done
diff_done = 0 diff_done = 0
@@ -754,9 +753,13 @@ class BlockImageDiff(object):
try: try:
patch = compute_patch(src_file, tgt_file, imgdiff) patch = compute_patch(src_file, tgt_file, imgdiff)
except ValueError as e: except ValueError as e:
raise ValueError( with lock:
"Failed to generate diff for %s: src=%s, tgt=%s: %s" % ( error_messages.append(
xf.tgt_name, xf.src_ranges, xf.tgt_ranges, e.message)) "Failed to generate %s for %s: tgt=%s, src=%s:\n%s" % (
"imgdiff" if imgdiff else "bsdiff",
xf.tgt_name if xf.tgt_name == xf.src_name else
xf.tgt_name + " (from " + xf.src_name + ")",
xf.tgt_ranges, xf.src_ranges, e.message))
with lock: with lock:
patches[patch_index] = (xf_index, patch) patches[patch_index] = (xf_index, patch)
@@ -777,6 +780,10 @@ class BlockImageDiff(object):
if sys.stdout.isatty(): if sys.stdout.isatty():
print('\n') print('\n')
if error_messages:
print('\n'.join(error_messages))
sys.exit(1)
else: else:
patches = [] patches = []