Util to load file contents into grpc_core::Slice (#31176)

* Util to load file contents into grpc_core::Slice

* Add test

* iwyu

* iwyu again
pull/31150/head^2
Vignesh Babu 3 years ago committed by GitHub
parent 6cac641c64
commit e1e1f6181f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 21
      BUILD
  2. 134
      CMakeLists.txt
  3. 83
      build_autogenerated.yaml
  4. 75
      src/core/lib/gprpp/load_file.cc
  5. 33
      src/core/lib/gprpp/load_file.h
  6. 1
      test/core/event_engine/BUILD
  7. 4
      test/core/event_engine/factory_test.cc
  8. 7
      test/core/event_engine/util/aborting_event_engine.h
  9. 15
      test/core/gprpp/BUILD
  10. 132
      test/core/gprpp/load_file_test.cc
  11. 72
      tools/run_tests/generated/tests.json

21
BUILD

@ -3444,6 +3444,27 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "load_file",
srcs = [
"src/core/lib/gprpp/load_file.cc",
],
hdrs = [
"src/core/lib/gprpp/load_file.h",
],
external_deps = [
"absl/cleanup",
"absl/status",
"absl/status:statusor",
"absl/strings",
],
language = "c++",
deps = [
"gpr",
"slice",
],
)
grpc_cc_library(
name = "http2_errors",
hdrs = [

134
CMakeLists.txt generated

@ -1039,7 +1039,6 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_cxx latch_test)
add_dependencies(buildtests_cxx lb_get_cpu_stats_test)
add_dependencies(buildtests_cxx lb_load_data_store_test)
add_dependencies(buildtests_cxx load_file_test)
add_dependencies(buildtests_cxx lock_free_event_test)
add_dependencies(buildtests_cxx log_test)
add_dependencies(buildtests_cxx loop_test)
@ -1193,7 +1192,9 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_cxx test_core_event_engine_posix_timer_list_test)
add_dependencies(buildtests_cxx test_core_event_engine_slice_buffer_test)
add_dependencies(buildtests_cxx test_core_gpr_time_test)
add_dependencies(buildtests_cxx test_core_gprpp_load_file_test)
add_dependencies(buildtests_cxx test_core_gprpp_time_test)
add_dependencies(buildtests_cxx test_core_iomgr_load_file_test)
add_dependencies(buildtests_cxx test_core_iomgr_timer_heap_test)
add_dependencies(buildtests_cxx test_core_security_credentials_test)
add_dependencies(buildtests_cxx test_core_slice_slice_buffer_test)
@ -13067,53 +13068,6 @@ target_link_libraries(lb_load_data_store_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(load_file_test
test/core/iomgr/load_file_test.cc
test/core/util/cmdline.cc
test/core/util/fuzzer_util.cc
test/core/util/grpc_profiler.cc
test/core/util/histogram.cc
test/core/util/mock_endpoint.cc
test/core/util/parse_hexstring.cc
test/core/util/passthru_endpoint.cc
test/core/util/resolve_localhost_ip46.cc
test/core/util/slice_splitter.cc
test/core/util/subprocess_posix.cc
test/core/util/subprocess_windows.cc
test/core/util/tracer_util.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(load_file_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_XXHASH_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
third_party/googletest/googletest/include
third_party/googletest/googletest
third_party/googletest/googlemock/include
third_party/googletest/googlemock
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(load_file_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
)
endif()
if(gRPC_BUILD_TESTS)
@ -18041,6 +17995,43 @@ target_link_libraries(test_core_gpr_time_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(test_core_gprpp_load_file_test
src/core/lib/gprpp/load_file.cc
test/core/gprpp/load_file_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(test_core_gprpp_load_file_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_XXHASH_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
third_party/googletest/googletest/include
third_party/googletest/googletest
third_party/googletest/googlemock/include
third_party/googletest/googlemock
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(test_core_gprpp_load_file_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
absl::cleanup
grpc_test_util
)
endif()
if(gRPC_BUILD_TESTS)
@ -18079,6 +18070,53 @@ target_link_libraries(test_core_gprpp_time_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(test_core_iomgr_load_file_test
test/core/iomgr/load_file_test.cc
test/core/util/cmdline.cc
test/core/util/fuzzer_util.cc
test/core/util/grpc_profiler.cc
test/core/util/histogram.cc
test/core/util/mock_endpoint.cc
test/core/util/parse_hexstring.cc
test/core/util/passthru_endpoint.cc
test/core/util/resolve_localhost_ip46.cc
test/core/util/slice_splitter.cc
test/core/util/subprocess_posix.cc
test/core/util/subprocess_windows.cc
test/core/util/tracer_util.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(test_core_iomgr_load_file_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_XXHASH_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
third_party/googletest/googletest/include
third_party/googletest/googletest
third_party/googletest/googlemock/include
third_party/googletest/googlemock
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(test_core_iomgr_load_file_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
)
endif()
if(gRPC_BUILD_TESTS)

@ -7556,41 +7556,6 @@ targets:
deps:
- grpc++
- grpc_test_util
- name: load_file_test
gtest: true
build: test
language: c++
headers:
- test/core/util/cmdline.h
- test/core/util/evaluate_args_test_util.h
- test/core/util/fuzzer_util.h
- test/core/util/grpc_profiler.h
- test/core/util/histogram.h
- test/core/util/mock_authorization_endpoint.h
- test/core/util/mock_endpoint.h
- test/core/util/parse_hexstring.h
- test/core/util/passthru_endpoint.h
- test/core/util/resolve_localhost_ip46.h
- test/core/util/slice_splitter.h
- test/core/util/subprocess.h
- test/core/util/tracer_util.h
src:
- test/core/iomgr/load_file_test.cc
- test/core/util/cmdline.cc
- test/core/util/fuzzer_util.cc
- test/core/util/grpc_profiler.cc
- test/core/util/histogram.cc
- test/core/util/mock_endpoint.cc
- test/core/util/parse_hexstring.cc
- test/core/util/passthru_endpoint.cc
- test/core/util/resolve_localhost_ip46.cc
- test/core/util/slice_splitter.cc
- test/core/util/subprocess_posix.cc
- test/core/util/subprocess_windows.cc
- test/core/util/tracer_util.cc
deps:
- grpc_test_util
uses_polling: false
- name: lock_free_event_test
gtest: true
build: test
@ -9882,6 +9847,19 @@ targets:
deps:
- grpc_test_util
uses_polling: false
- name: test_core_gprpp_load_file_test
gtest: true
build: test
language: c++
headers:
- src/core/lib/gprpp/load_file.h
src:
- src/core/lib/gprpp/load_file.cc
- test/core/gprpp/load_file_test.cc
deps:
- absl/cleanup:cleanup
- grpc_test_util
uses_polling: false
- name: test_core_gprpp_time_test
gtest: true
build: test
@ -9896,6 +9874,41 @@ targets:
- absl/status:statusor
- gpr
uses_polling: false
- name: test_core_iomgr_load_file_test
gtest: true
build: test
language: c++
headers:
- test/core/util/cmdline.h
- test/core/util/evaluate_args_test_util.h
- test/core/util/fuzzer_util.h
- test/core/util/grpc_profiler.h
- test/core/util/histogram.h
- test/core/util/mock_authorization_endpoint.h
- test/core/util/mock_endpoint.h
- test/core/util/parse_hexstring.h
- test/core/util/passthru_endpoint.h
- test/core/util/resolve_localhost_ip46.h
- test/core/util/slice_splitter.h
- test/core/util/subprocess.h
- test/core/util/tracer_util.h
src:
- test/core/iomgr/load_file_test.cc
- test/core/util/cmdline.cc
- test/core/util/fuzzer_util.cc
- test/core/util/grpc_profiler.cc
- test/core/util/histogram.cc
- test/core/util/mock_endpoint.cc
- test/core/util/parse_hexstring.cc
- test/core/util/passthru_endpoint.cc
- test/core/util/resolve_localhost_ip46.cc
- test/core/util/slice_splitter.cc
- test/core/util/subprocess_posix.cc
- test/core/util/subprocess_windows.cc
- test/core/util/tracer_util.cc
deps:
- grpc_test_util
uses_polling: false
- name: test_core_iomgr_timer_heap_test
gtest: true
build: test

@ -0,0 +1,75 @@
// Copyright 2022 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include "src/core/lib/gprpp/load_file.h"
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "absl/cleanup/cleanup.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include <grpc/slice.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
namespace grpc_core {
// Loads the content of a file into a slice. add_null_terminator will add a NULL
// terminator if true.
absl::StatusOr<Slice> LoadFile(std::string filename, bool add_null_terminator) {
unsigned char* contents = nullptr;
size_t contents_size = 0;
FILE* file;
size_t bytes_read = 0;
absl::Status error = absl::OkStatus();
auto sock_cleanup = absl::MakeCleanup([&file]() -> void {
if (file != nullptr) {
fclose(file);
}
});
file = fopen(filename.c_str(), "rb");
if (file == nullptr) {
error = absl::InternalError(
absl::StrCat("Failed to load file: ", filename,
" due to error(fdopen): ", strerror(errno)));
return error;
}
fseek(file, 0, SEEK_END);
// Converting to size_t on the assumption that it will not fail.
contents_size = static_cast<size_t>(ftell(file));
fseek(file, 0, SEEK_SET);
contents = static_cast<unsigned char*>(
gpr_malloc(contents_size + (add_null_terminator ? 1 : 0)));
bytes_read = fread(contents, 1, contents_size, file);
if (bytes_read < contents_size) {
gpr_free(contents);
GPR_ASSERT(ferror(file));
error = absl::InternalError(
absl::StrCat("Failed to load file: ", filename,
" due to error(fread): ", strerror(errno)));
return error;
}
if (add_null_terminator) {
contents[contents_size++] = 0;
}
return Slice(grpc_slice_new(contents, contents_size, gpr_free));
}
} // namespace grpc_core

@ -0,0 +1,33 @@
// Copyright 2022 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_CORE_LIB_GPRPP_LOAD_FILE_H
#define GRPC_CORE_LIB_GPRPP_LOAD_FILE_H
#include <grpc/support/port_platform.h>
#include <string>
#include "absl/status/statusor.h"
#include "src/core/lib/slice/slice.h"
namespace grpc_core {
// Loads the content of a file into a slice. add_null_terminator will add a NULL
// terminator if true.
absl::StatusOr<Slice> LoadFile(std::string filename, bool add_null_terminator);
} // namespace grpc_core
#endif // GRPC_CORE_LIB_GPRPP_LOAD_FILE_H

@ -150,6 +150,7 @@ grpc_cc_library(
testonly = True,
hdrs = ["util/aborting_event_engine.h"],
external_deps = [
"absl/functional:any_invocable",
"absl/status",
"absl/status:statusor",
],

@ -14,7 +14,9 @@
#include <grpc/support/port_platform.h>
#include <gtest/gtest.h>
#include <memory>
#include "gtest/gtest.h"
#include <grpc/event_engine/event_engine.h>
#include <grpc/grpc.h>

@ -16,10 +16,17 @@
#include <grpc/support/port_platform.h>
#include <stdlib.h>
#include <memory>
#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include <grpc/event_engine/endpoint_config.h>
#include <grpc/event_engine/event_engine.h>
#include <grpc/event_engine/memory_allocator.h>
namespace grpc_event_engine {
namespace experimental {

@ -429,3 +429,18 @@ grpc_cc_test(
uses_polling = False,
deps = ["//:notification"],
)
grpc_cc_test(
name = "load_file_test",
srcs = ["load_file_test.cc"],
external_deps = [
"gtest",
],
language = "C++",
uses_event_engine = False,
uses_polling = False,
deps = [
"//:load_file",
"//test/core/util:grpc_test_util",
],
)

@ -0,0 +1,132 @@
// Copyright 2022 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/core/lib/gprpp/load_file.h"
#include <stdio.h>
#include <string.h>
#include <cstdint>
#include "gtest/gtest.h"
#include <grpc/support/alloc.h>
#include "src/core/lib/gpr/tmpfile.h"
#include "test/core/util/test_config.h"
static const char prefix[] = "file_test";
TEST(LoadFileTest, TestLoadEmptyFile) {
FILE* tmp = nullptr;
absl::StatusOr<grpc_core::Slice> result;
char* tmp_name;
tmp = gpr_tmpfile(prefix, &tmp_name);
ASSERT_NE(tmp_name, nullptr);
ASSERT_NE(tmp, nullptr);
fclose(tmp);
result = grpc_core::LoadFile(tmp_name, false);
ASSERT_TRUE(result.ok());
ASSERT_EQ(result->length(), 0);
result = grpc_core::LoadFile(tmp_name, true);
ASSERT_TRUE(result.ok());
ASSERT_EQ(result->length(), 1);
ASSERT_EQ(result->begin()[0], 0);
remove(tmp_name);
gpr_free(tmp_name);
}
TEST(LoadFileTest, TestLoadFailure) {
FILE* tmp = nullptr;
absl::StatusOr<grpc_core::Slice> result;
char* tmp_name;
tmp = gpr_tmpfile(prefix, &tmp_name);
ASSERT_NE(tmp_name, nullptr);
ASSERT_NE(tmp, nullptr);
fclose(tmp);
remove(tmp_name);
result = grpc_core::LoadFile(tmp_name, false);
ASSERT_FALSE(result.ok());
gpr_free(tmp_name);
}
TEST(LoadFileTest, TestLoadSmallFile) {
FILE* tmp = nullptr;
absl::StatusOr<grpc_core::Slice> result;
char* tmp_name;
const char* blah = "blah";
tmp = gpr_tmpfile(prefix, &tmp_name);
ASSERT_NE(tmp_name, nullptr);
ASSERT_NE(tmp, nullptr);
ASSERT_EQ(fwrite(blah, 1, strlen(blah), tmp), strlen(blah));
fclose(tmp);
result = grpc_core::LoadFile(tmp_name, false);
ASSERT_TRUE(result.ok());
ASSERT_EQ(result->length(), strlen(blah));
ASSERT_FALSE(memcmp(result->begin(), blah, strlen(blah)));
result = grpc_core::LoadFile(tmp_name, true);
ASSERT_TRUE(result.ok());
ASSERT_EQ(result->length(), strlen(blah) + 1);
ASSERT_STREQ(reinterpret_cast<const char*>(result->begin()), blah);
remove(tmp_name);
gpr_free(tmp_name);
}
TEST(LoadFileTest, TestLoadBigFile) {
FILE* tmp = nullptr;
absl::StatusOr<grpc_core::Slice> result;
char* tmp_name;
static const size_t buffer_size = 124631;
unsigned char* buffer = static_cast<unsigned char*>(gpr_malloc(buffer_size));
const uint8_t* current;
size_t i;
memset(buffer, 42, buffer_size);
tmp = gpr_tmpfile(prefix, &tmp_name);
ASSERT_NE(tmp, nullptr);
ASSERT_NE(tmp_name, nullptr);
ASSERT_EQ(fwrite(buffer, 1, buffer_size, tmp), buffer_size);
fclose(tmp);
result = grpc_core::LoadFile(tmp_name, false);
ASSERT_TRUE(result.ok());
ASSERT_EQ(result->length(), buffer_size);
current = result->begin();
for (i = 0; i < buffer_size; i++) {
ASSERT_EQ(current[i], 42);
}
remove(tmp_name);
gpr_free(tmp_name);
gpr_free(buffer);
}
int main(int argc, char** argv) {
grpc::testing::TestEnvironment env(&argc, argv);
::testing::InitGoogleTest(&argc, argv);
grpc::testing::TestGrpcScope grpc_scope;
return RUN_ALL_TESTS();
}

@ -4409,30 +4409,6 @@
],
"uses_polling": true
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": true,
"language": "c++",
"name": "load_file_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": false
},
{
"args": [],
"benchmark": false,
@ -7037,6 +7013,30 @@
],
"uses_polling": false
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": true,
"language": "c++",
"name": "test_core_gprpp_load_file_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": false
},
{
"args": [],
"benchmark": false,
@ -7061,6 +7061,30 @@
],
"uses_polling": false
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": true,
"language": "c++",
"name": "test_core_iomgr_load_file_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": false
},
{
"args": [],
"benchmark": false,

Loading…
Cancel
Save