Make bash processing stricter and refactor a bit

Perl outputs an error if it encounters an invalid utf-8 character in the
input, which means that the current script doesn't actually work, at
least as of perl v5.24.1.

I don't think we currently do anything with the exit code in Bazel, but
at least we can get it and output a warning or even an error, after this
change.

PiperOrigin-RevId: 229562020
diff --git a/tools/test/generate-xml.sh b/tools/test/generate-xml.sh
index 730b131..3a3de60 100644
--- a/tools/test/generate-xml.sh
+++ b/tools/test/generate-xml.sh
@@ -14,13 +14,15 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+set -euo pipefail
+
 TEST_LOG="$1"
 XML_OUTPUT_FILE="$2"
 DURATION_IN_SECONDS="$3"
 EXIT_CODE="$4"
 
 # Keep this in sync with test-setup.sh!
-function encode_output_file {
+function encode_as_xml {
   if [[ -f "$1" ]]; then
     # Replace invalid XML characters and invalid sequence in CDATA
     # cf. https://stackoverflow.com/a/7774512/4717701
@@ -43,13 +45,15 @@
   test_name="${test_name}"_shard_"${shard_num}"/"${TEST_TOTAL_SHARDS}"
 fi
 
+FAILED=0
+ENCODED_LOG="$(encode_as_xml "${TEST_LOG}")" || FAILED=1
 cat <<EOF >${XML_OUTPUT_FILE}
 <?xml version="1.0" encoding="UTF-8"?>
 <testsuites>
 <testsuite name="${test_name}" tests="1" failures="0" errors="${errors}">
   <testcase name="${test_name}" status="run" duration="${DURATION_IN_SECONDS}" time="${DURATION_IN_SECONDS}">${error_msg}</testcase>
-  <system-out><![CDATA[$(encode_output_file "${TEST_LOG}")]]></system-out>
+  <system-out><![CDATA[${ENCODED_LOG}]]></system-out>
 </testsuite>
 </testsuites>
 EOF
-
+exit "$FAILED"