Merge "Check the state of ofstream"

This commit is contained in:
Hsin-Yi Chen
2023-06-26 06:02:25 +00:00
committed by Gerrit Code Review
5 changed files with 98 additions and 30 deletions

View File

@@ -373,7 +373,7 @@ static std::string DumpJson(const JsonObject &obj) {
return Json::writeString(factory, obj);
}
static void WriteTailTrimmedLinesToFile(const std::string &path,
static bool WriteTailTrimmedLinesToFile(const std::string &path,
const std::string &output_string) {
std::ofstream output_file(path);
size_t line_start = 0;
@@ -389,19 +389,25 @@ static void WriteTailTrimmedLinesToFile(const std::string &path,
}
// Only write this line if this line contains non-whitespace characters.
if (trailing_space_start != line_start) {
output_file.write(output_string.data() + line_start,
trailing_space_start - line_start);
output_file.write("\n", 1);
if (output_file
.write(output_string.data() + line_start,
trailing_space_start - line_start)
.fail()) {
return false;
}
if (output_file.write("\n", 1).fail()) {
return false;
}
}
line_start = index + 1;
}
return output_file.flush().good();
}
bool JsonIRDumper::Dump(const ModuleIR &module) {
DumpModule(module);
std::string output_string = DumpJson(translation_unit_);
WriteTailTrimmedLinesToFile(dump_path_, output_string);
return true;
return WriteTailTrimmedLinesToFile(dump_path_, output_string);
}
JsonIRDumper::JsonIRDumper(const std::string &dump_path)

View File

@@ -378,8 +378,13 @@ bool ProtobufIRDiffDumper::Dump() {
GOOGLE_PROTOBUF_VERIFY_VERSION;
assert(diff_tu_.get() != nullptr);
std::ofstream text_output(dump_path_);
google::protobuf::io::OstreamOutputStream text_os(&text_output);
return google::protobuf::TextFormat::Print(*diff_tu_.get(), &text_os);
{
google::protobuf::io::OstreamOutputStream text_os(&text_output);
if (!google::protobuf::TextFormat::Print(*diff_tu_.get(), &text_os)) {
return false;
}
}
return text_output.flush().good();
}
std::unique_ptr<IRDiffDumper> CreateProtobufIRDiffDumper(

View File

@@ -477,8 +477,13 @@ bool ProtobufIRDumper::Dump(const ModuleIR &module) {
DumpModule(module);
assert( tu_ptr_.get() != nullptr);
std::ofstream text_output(dump_path_);
google::protobuf::io::OstreamOutputStream text_os(&text_output);
return google::protobuf::TextFormat::Print(*tu_ptr_.get(), &text_os);
{
google::protobuf::io::OstreamOutputStream text_os(&text_output);
if (!google::protobuf::TextFormat::Print(*tu_ptr_.get(), &text_os)) {
return false;
}
}
return text_output.flush().good();
}
std::unique_ptr<IRDumper> CreateProtobufIRDumper(const std::string &dump_path) {

View File

@@ -2,6 +2,7 @@
import os
import shutil
import stat
import subprocess
import sys
import tempfile
@@ -11,7 +12,8 @@ import_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
import_path = os.path.abspath(os.path.join(import_path, 'utils'))
sys.path.insert(1, import_path)
from utils import run_abi_diff, run_header_abi_dumper
from utils import (run_abi_diff, run_and_read_abi_diff, run_header_abi_dumper,
run_header_abi_linker)
from module import Module
@@ -78,8 +80,8 @@ class HeaderCheckerTest(unittest.TestCase):
def run_and_compare_abi_diff(self, old_dump, new_dump, lib, arch,
expected_return_code, flags=[]):
return_code, output = run_abi_diff(old_dump, new_dump, arch, lib,
flags)
return_code, output = run_and_read_abi_diff(
old_dump, new_dump, arch, lib, flags)
self.assertEqual(return_code, expected_return_code)
return output
@@ -488,6 +490,54 @@ class HeaderCheckerTest(unittest.TestCase):
def test_enum_diff(self):
self.prepare_and_absolute_diff_all_archs("libenum", "libenum")
def test_io_error(self):
cpp_path = os.path.join(self.get_tmp_dir(), "test.cpp")
sdump_path = os.path.join(self.get_tmp_dir(), "test.sdump")
version_script_path = os.path.join(self.get_tmp_dir(), "map.txt")
lsdump_path = os.path.join(self.get_tmp_dir(), "test.lsdump")
abidiff_path = os.path.join(self.get_tmp_dir(), "test.abidiff")
read_only_path = os.path.join(self.get_tmp_dir(), "read_only.txt")
with open(cpp_path, "w") as cpp_file:
cpp_file.write("void func(int) {}")
with open(version_script_path, "w") as version_script_file:
pass
fd = os.open(read_only_path, flags=(os.O_CREAT | os.O_EXCL),
mode=(stat.S_IROTH | stat.S_IRGRP | stat.S_IRUSR))
self.assertGreaterEqual(fd, 0)
os.close(fd)
# Make sure that the commands are valid.
dumper_flags = ('-output-format', 'Json')
run_header_abi_dumper(cpp_path, sdump_path, flags=dumper_flags)
self.assertGreater(os.stat(sdump_path).st_size, 0)
linker_flags = ('-input-format', 'Json',
'-output-format', 'ProtobufTextFormat')
run_header_abi_linker([sdump_path], lsdump_path, version_script_path,
"current", "x86_64", linker_flags)
self.assertGreater(os.stat(lsdump_path).st_size, 0)
diff_flags = ('-input-format-old', 'ProtobufTextFormat',
'-input-format-new', 'ProtobufTextFormat')
return_code = run_abi_diff(lsdump_path, lsdump_path, abidiff_path,
'x86_64', 'libtest', diff_flags)
self.assertEqual(return_code, 0)
self.assertGreater(os.stat(abidiff_path).st_size, 0)
# Test with output error.
with self.assertRaises(subprocess.CalledProcessError) as assertion:
run_header_abi_dumper(cpp_path, read_only_path, flags=dumper_flags)
self.assertEqual(assertion.exception.returncode, 1)
with self.assertRaises(subprocess.CalledProcessError) as assertion:
run_header_abi_linker([sdump_path], read_only_path,
version_script_path, "current", "x86_64",
linker_flags)
self.assertEqual(assertion.exception.returncode, 255)
return_code = run_abi_diff(lsdump_path, lsdump_path, read_only_path,
'x86_64', 'libtest', diff_flags)
self.assertEqual(return_code, 1)
if __name__ == '__main__':
unittest.main()

View File

@@ -293,25 +293,27 @@ def find_lib_lsdumps(lsdump_paths, libs, target):
return [(tag, os.path.join(AOSP_DIR, path)) for tag, path in result]
def run_abi_diff(old_test_dump_path, new_test_dump_path, arch, lib_name,
flags=tuple()):
abi_diff_cmd = ['header-abi-diff', '-new', new_test_dump_path, '-old',
old_test_dump_path, '-arch', arch, '-lib', lib_name]
def run_abi_diff(old_dump_path, new_dump_path, output_path, arch, lib_name,
flags):
abi_diff_cmd = ['header-abi-diff', '-new', new_dump_path, '-old',
old_dump_path, '-arch', arch, '-lib', lib_name,
'-o', output_path]
abi_diff_cmd += flags
if '-input-format-old' not in flags:
abi_diff_cmd += ['-input-format-old', DEFAULT_FORMAT]
if '-input-format-new' not in flags:
abi_diff_cmd += ['-input-format-new', DEFAULT_FORMAT]
return subprocess.run(abi_diff_cmd).returncode
def run_and_read_abi_diff(old_dump_path, new_dump_path, arch, lib_name,
flags=tuple()):
with tempfile.TemporaryDirectory() as tmp:
output_name = os.path.join(tmp, lib_name) + '.abidiff'
abi_diff_cmd += ['-o', output_name]
abi_diff_cmd += flags
if '-input-format-old' not in flags:
abi_diff_cmd += ['-input-format-old', DEFAULT_FORMAT]
if '-input-format-new' not in flags:
abi_diff_cmd += ['-input-format-new', DEFAULT_FORMAT]
result = subprocess.run(abi_diff_cmd)
output = ""
if os.path.isfile(output_name):
with open(output_name, 'r') as output_file:
output = output_file.read()
return result.returncode, output
result = run_abi_diff(old_dump_path, new_dump_path, output_name, arch,
lib_name, flags)
with open(output_name, 'r') as output_file:
return result, output_file.read()
def get_build_vars_for_product(names, product=None, variant=None):