| /* |
| * Copyright (C) 2018 The Android Open Source Project |
| * |
| * 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 "perfetto/ext/base/temp_file.h" |
| |
| #include <sys/stat.h> |
| |
| #include "perfetto/base/build_config.h" |
| |
| #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) |
| #include <unistd.h> |
| #endif |
| |
| #include "test/gtest_and_gmock.h" |
| |
| namespace perfetto { |
| namespace base { |
| namespace { |
| |
| bool PathExists(const std::string& path) { |
| struct stat stat_buf; |
| return stat(path.c_str(), &stat_buf) == 0; |
| } |
| |
| TEST(TempFileTest, Create) { |
| std::string path; |
| int fd; |
| { |
| TempFile tf = TempFile::Create(); |
| path = tf.path(); |
| fd = tf.fd(); |
| ASSERT_NE("", path); |
| ASSERT_GE(fd, 0); |
| ASSERT_TRUE(PathExists(path)); |
| ASSERT_GE(write(fd, "foo", 4), 0); |
| |
| TempFile moved_tf(std::move(tf)); |
| ASSERT_EQ("", tf.path()); |
| ASSERT_EQ(-1, tf.fd()); |
| ASSERT_EQ(path, moved_tf.path()); |
| ASSERT_EQ(fd, moved_tf.fd()); |
| ASSERT_GE(write(moved_tf.fd(), "foo", 4), 0); |
| |
| TempFile moved_tf2 = std::move(moved_tf); |
| ASSERT_EQ("", moved_tf.path()); |
| ASSERT_EQ(-1, moved_tf.fd()); |
| ASSERT_EQ(path, moved_tf2.path()); |
| ASSERT_EQ(fd, moved_tf2.fd()); |
| ASSERT_GE(write(moved_tf2.fd(), "foo", 4), 0); |
| } |
| |
| // The file should be deleted and closed now. |
| ASSERT_FALSE(PathExists(path)); |
| |
| #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) |
| // Windows UCRT aborts when trying to write into a closed FD. |
| ASSERT_EQ(-1, write(fd, "foo", 4)); |
| #endif |
| } |
| |
| TEST(TempFileTest, CreateUnlinked) { |
| int fd; |
| { |
| TempFile tf = TempFile::CreateUnlinked(); |
| ASSERT_EQ("", tf.path()); |
| fd = tf.fd(); |
| ASSERT_GE(fd, 0); |
| ASSERT_GE(write(fd, "foo", 4), 0); |
| } |
| |
| #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) |
| // Windows UCRT aborts when trying to write into a closed FD. |
| ASSERT_EQ(-1, write(fd, "foo", 4)); |
| #endif |
| } |
| |
| TEST(TempFileTest, ReleaseUnlinked) { |
| ScopedFile fd; |
| { |
| TempFile tf = TempFile::Create(); |
| fd = tf.ReleaseFD(); |
| } |
| ASSERT_GE(write(*fd, "foo", 4), 0); |
| } |
| |
| TEST(TempFileTest, ReleaseLinked) { |
| ScopedFile fd; |
| std::string path; |
| { |
| TempFile tf = TempFile::CreateUnlinked(); |
| path = tf.path(); |
| fd = tf.ReleaseFD(); |
| } |
| |
| // The file should be unlinked from the filesystem. |
| ASSERT_FALSE(PathExists(path)); |
| |
| // But still open and writable. |
| ASSERT_GE(write(*fd, "foo", 4), 0); |
| } |
| |
| TEST(TempFileTest, TempDir) { |
| std::string path; |
| { |
| TempDir td = TempDir::Create(); |
| ASSERT_NE("", td.path()); |
| ASSERT_TRUE(PathExists(td.path())); |
| path = td.path(); |
| } |
| ASSERT_FALSE(PathExists(path)); |
| } |
| |
| } // namespace |
| } // namespace base |
| } // namespace perfetto |