Commit 301470a8 authored by Gabriel Charette's avatar Gabriel Charette Committed by Commit Bot

Reland "[FileUtil] Test thread-safety of temp file APIs."

This is a reland of 20a5f39c

Patch set 1 is the original change. Diff fixes the following compile
error on official builders :

../../base/files/file_util_unittest.cc:3674:5: error: ignoring return value of function declared with 'warn_unused_result' attribute [-Werror,-Wunused-result]
    ::write(::fileno(output_file.get()), content.c_str(), content.length());

Original change's description:
> [FileUtil] Test thread-safety of temp file APIs.
>
> Ruling out https://crbug.com/826408#c17 as the source of the issue.
>
> R=thestig@chromium.org
>
> Bug: 826408
> Change-Id: I00396084d674fa2f700eb917300280b6eed1684d
> Reviewed-on: https://chromium-review.googlesource.com/1072030
> Commit-Queue: Gabriel Charette <gab@chromium.org>
> Reviewed-by: Lei Zhang <thestig@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#561666}

TBR=thestig@chromium.org

Bug: 826408
Change-Id: Ifa37f12e708357fe7e6ce7a2dd688eab1e0a2324
Reviewed-on: https://chromium-review.googlesource.com/1073090Reviewed-by: default avatarGabriel Charette <gab@chromium.org>
Commit-Queue: Gabriel Charette <gab@chromium.org>
Cr-Commit-Position: refs/heads/master@{#561867}
parent 12595546
......@@ -4,6 +4,7 @@
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <algorithm>
#include <fstream>
......@@ -25,6 +26,7 @@
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/files/scoped_temp_dir.h"
#include "base/guid.h"
#include "base/macros.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
......@@ -34,6 +36,7 @@
#include "base/test/test_file_util.h"
#include "base/test/test_timeouts.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"
......@@ -3637,6 +3640,64 @@ TEST_F(FileUtilTest, NonExistentContentUriTest) {
}
#endif
// Test that temp files obtained racily are all unique (no interference between
// threads). Mimics file operations in DoLaunchChildTestProcess() to rule out
// thread-safety issues @ https://crbug.com/826408#c17.
TEST(FileUtilMultiThreadedTest, MultiThreadedTempFiles) {
constexpr int kNumThreads = 64;
constexpr int kNumWritesPerThread = 32;
std::unique_ptr<Thread> threads[kNumThreads];
for (auto& thread : threads) {
thread = std::make_unique<Thread>("test worker");
thread->Start();
}
// Wait until all threads are started for max parallelism.
for (auto& thread : threads)
thread->WaitUntilThreadStarted();
const RepeatingClosure open_write_close_read = BindRepeating([]() {
FilePath output_filename;
ScopedFILE output_file(CreateAndOpenTemporaryFile(&output_filename));
EXPECT_TRUE(output_file);
const std::string content = GenerateGUID();
#if defined(OS_WIN)
HANDLE handle =
reinterpret_cast<HANDLE>(_get_osfhandle(_fileno(output_file.get())));
DWORD bytes_written = 0;
::WriteFile(handle, content.c_str(), content.length(), &bytes_written,
NULL);
#else
size_t bytes_written =
::write(::fileno(output_file.get()), content.c_str(), content.length());
#endif
EXPECT_EQ(content.length(), bytes_written);
::fflush(output_file.get());
output_file.reset();
std::string output_file_contents;
EXPECT_TRUE(ReadFileToString(output_filename, &output_file_contents))
<< output_filename;
EXPECT_EQ(content, output_file_contents);
DeleteFile(output_filename, false);
});
// Post tasks to each thread in a round-robin fashion to ensure as much
// parallelism as possible.
for (int i = 0; i < kNumWritesPerThread; ++i) {
for (auto& thread : threads) {
thread->task_runner()->PostTask(FROM_HERE, open_write_close_read);
}
}
for (auto& thread : threads)
thread->Stop();
}
#if defined(OS_POSIX) || defined(OS_FUCHSIA)
TEST(ScopedFD, ScopedFDDoesClose) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment