fromupstream: preserve multi-line TEST description when using --replace

Test data set 1:
$ cat <<EOF | git commit --allow-empty -F -
> Commit title
>
> Description
>
> BUG=b:1
> TEST=1
> TEST=2
> TEST=line 1
> line 2
> TEST=another line 1
> another line 2
>
> TEST=yet another line 1
> yet another line 2
> BUG=b:2,b:3
>
> Cq-Depend: 1, 2, 3
> Cq-Depend: 4
> Change-Id: XXX

$ fromupstream.py --nosignoff -r linux://238c30468f46b

$ git show -s
> [snip]
> BUG=b:1
> BUG=b:2,b:3
> TEST=1
> TEST=2
> TEST=line 1
> line 2
> TEST=another line 1
> another line 2
> TEST=yet another line 1
> yet another line 2
>
> Cq-Depend: 1, 2, 3
> Cq-Depend: 4
> Change-Id: XXX

$ git rebase --onto HEAD~1 HEAD

Test data set 2:
$ cat <<EOF | git commit --allow-empty -F -
> Commit title
>
> Description
>
> BUG=b:1
> TEST=1
> TEST=2
> TEST=line 1
> line 2
> TEST=another line 1
> another line 2
>
> TEST=yet another line 1
> yet another line 2
> BUG=b:2,b:3
> Change-Id: XXX
> EOF

$ fromupstream.py --nosignoff -r linux://238c30468f46b

$ git show -s
> [snip]
> BUG=b:1
> BUG=b:2,b:3
> TEST=1
> TEST=2
> TEST=line 1
> line 2
> TEST=another line 1
> another line 2
> TEST=yet another line 1
> yet another line 2
>
> Change-Id: XXX

$ git rebase --onto HEAD~1 HEAD

BUG=none
TEST=as shown above

Change-Id: I8a52f6895fb118c0a507cdc6bd0cc2f18eca161f
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/dev-util/+/2345648
Tested-by: Tzung-Bi Shih <tzungbi@chromium.org>
Commit-Queue: Tzung-Bi Shih <tzungbi@chromium.org>
Reviewed-by: Brian Norris <briannorris@chromium.org>
Reviewed-by: Alexandru M Stan <amstan@chromium.org>
diff --git a/contrib/fromupstream.py b/contrib/fromupstream.py
index be8f830..ce24178 100755
--- a/contrib/fromupstream.py
+++ b/contrib/fromupstream.py
@@ -478,10 +478,19 @@
         if args['bug'] is None and bugs:
             args['bug'] = '\nBUG='.join(bugs)
 
-        tests = re.findall('^TEST=(.*)$', old_commit_message, re.MULTILINE)
+        # Note: use (?=...) to avoid to consume the source string
+        tests = re.findall(r"""
+            ^TEST=(.*?)     # Match start from TEST= until
+            \n              # (to remove the tailing newlines)
+            (?=^$|          # a blank line
+               ^Cq-Depend:| # or Cq-Depend:
+               ^Change-Id:| # or Change-Id:
+               ^BUG=|       # or following BUG=
+               ^TEST=)      # or another TEST=
+            """,
+            old_commit_message, re.MULTILINE | re.DOTALL | re.VERBOSE)
         if args['test'] is None and tests:
             args['test'] = '\nTEST='.join(tests)
-        # TODO: deal with multiline BUG/TEST better
 
     if args['bug'] is None or args['test'] is None:
         parser.error('BUG=/TEST= lines are required; --replace can help '