brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.8 KiB · ed4ba26 Raw
188 lines · cpp
1//===-- Unittests for file operations like fopen, flcose etc --------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "src/stdio/clearerr.h"10#include "src/stdio/fclose.h"11#include "src/stdio/feof.h"12#include "src/stdio/ferror.h"13#include "src/stdio/fflush.h"14#include "src/stdio/fileno.h"15#include "src/stdio/fopen.h"16#include "src/stdio/fputs.h"17#include "src/stdio/fread.h"18#include "src/stdio/fseek.h"19#include "src/stdio/fwrite.h"20#include "test/UnitTest/ErrnoCheckingTest.h"21#include "test/UnitTest/ErrnoSetterMatcher.h"22#include "test/UnitTest/Test.h"23 24#include "hdr/stdio_macros.h"25 26using LlvmLibcFILETest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;27using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::EQ;28using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::NE;29using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::returns;30 31TEST_F(LlvmLibcFILETest, SimpleFileOperations) {32  constexpr char FILENAME[] =33      APPEND_LIBC_TEST("testdata/simple_operations.test");34  ::FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w");35  ASSERT_FALSE(file == nullptr);36  ASSERT_GE(LIBC_NAMESPACE::fileno(file), 0);37  constexpr char CONTENT[] = "1234567890987654321";38  ASSERT_EQ(sizeof(CONTENT) - 1,39            LIBC_NAMESPACE::fwrite(CONTENT, 1, sizeof(CONTENT) - 1, file));40 41  // This is not a readable file.42  char read_data[sizeof(CONTENT)];43  ASSERT_THAT(LIBC_NAMESPACE::fread(read_data, 1, sizeof(CONTENT), file),44              returns(EQ(size_t(0))).with_errno(NE(0)));45  ASSERT_NE(LIBC_NAMESPACE::ferror(file), 0);46 47  LIBC_NAMESPACE::clearerr(file);48  ASSERT_EQ(LIBC_NAMESPACE::ferror(file), 0);49 50  ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file));51 52  file = LIBC_NAMESPACE::fopen(FILENAME, "r");53  ASSERT_FALSE(file == nullptr);54 55  constexpr size_t READ_SIZE = 5;56  char data[READ_SIZE];57  data[READ_SIZE - 1] = '\0';58  ASSERT_EQ(LIBC_NAMESPACE::fread(data, 1, READ_SIZE - 1, file), READ_SIZE - 1);59  ASSERT_STREQ(data, "1234");60  ASSERT_EQ(LIBC_NAMESPACE::fseek(file, 5, SEEK_CUR), 0);61  ASSERT_EQ(LIBC_NAMESPACE::fread(data, 1, READ_SIZE - 1, file), READ_SIZE - 1);62  ASSERT_STREQ(data, "0987");63  ASSERT_EQ(LIBC_NAMESPACE::fseek(file, -5, SEEK_CUR), 0);64  ASSERT_EQ(LIBC_NAMESPACE::fread(data, 1, READ_SIZE - 1, file), READ_SIZE - 1);65  ASSERT_STREQ(data, "9098");66 67  // Reading another time should trigger eof.68  ASSERT_NE(sizeof(CONTENT),69            LIBC_NAMESPACE::fread(read_data, 1, sizeof(CONTENT), file));70  ASSERT_NE(LIBC_NAMESPACE::feof(file), 0);71 72  // Should be an error to write.73  ASSERT_THAT(LIBC_NAMESPACE::fwrite(CONTENT, 1, sizeof(CONTENT), file),74              returns(EQ(size_t(0))).with_errno(NE(0)));75  ASSERT_NE(LIBC_NAMESPACE::ferror(file), 0);76 77  LIBC_NAMESPACE::clearerr(file);78 79  // Should be an error to puts.80  ASSERT_THAT(LIBC_NAMESPACE::fputs(CONTENT, file),81              returns(EQ(EOF)).with_errno(NE(0)));82  ASSERT_NE(LIBC_NAMESPACE::ferror(file), 0);83 84  LIBC_NAMESPACE::clearerr(file);85  ASSERT_EQ(LIBC_NAMESPACE::ferror(file), 0);86 87  ASSERT_THAT(LIBC_NAMESPACE::fwrite("nothing", 1, 1, file),88              returns(EQ(size_t(0))).with_errno(NE(0)));89 90  ASSERT_EQ(LIBC_NAMESPACE::fclose(file), 0);91 92  // Now try puts.93  file = LIBC_NAMESPACE::fopen(FILENAME, "w");94  ASSERT_FALSE(file == nullptr);95  // fputs returns a negative value on error (EOF) or any non-negative value on96  // success. This assert checks that the return value is non-negative.97  ASSERT_GE(LIBC_NAMESPACE::fputs(CONTENT, file), 0);98 99  LIBC_NAMESPACE::clearerr(file);100  ASSERT_EQ(LIBC_NAMESPACE::ferror(file), 0);101 102  // This is not a readable file.103  ASSERT_THAT(LIBC_NAMESPACE::fread(data, 1, 1, file),104              returns(EQ(size_t(0))).with_errno(NE(0)));105 106  ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file));107 108  file = LIBC_NAMESPACE::fopen(FILENAME, "r");109  ASSERT_FALSE(file == nullptr);110 111  ASSERT_EQ(LIBC_NAMESPACE::fread(read_data, 1, sizeof(CONTENT) - 1, file),112            sizeof(CONTENT) - 1);113  read_data[sizeof(CONTENT) - 1] = '\0';114  ASSERT_STREQ(read_data, CONTENT);115  ASSERT_EQ(LIBC_NAMESPACE::fclose(file), 0);116 117  // Check that the other functions correctly set libc_errno.118 119  // ASSERT_NE(LIBC_NAMESPACE::fseek(file, 0, SEEK_SET), 0);120  // ASSERT_ERRNO_FAILURE();121 122  // ASSERT_NE(LIBC_NAMESPACE::fclose(file), 0);123  // ASSERT_ERRNO_FAILURE();124 125  // ASSERT_EQ(LIBC_NAMESPACE::fopen("INVALID FILE NAME", "r"),126  //           static_cast<FILE *>(nullptr));127  // ASSERT_ERRNO_FAILURE();128}129 130TEST_F(LlvmLibcFILETest, FFlush) {131  constexpr char FILENAME[] = APPEND_LIBC_TEST("testdata/fflush.test");132  ::FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w+");133  ASSERT_FALSE(file == nullptr);134  constexpr char CONTENT[] = "1234567890987654321";135  ASSERT_EQ(sizeof(CONTENT),136            LIBC_NAMESPACE::fwrite(CONTENT, 1, sizeof(CONTENT), file));137 138  // Flushing at this point should write the data to disk. So, we should be139  // able to read it back.140  ASSERT_EQ(0, LIBC_NAMESPACE::fflush(file));141 142  char data[sizeof(CONTENT)];143  ASSERT_EQ(LIBC_NAMESPACE::fseek(file, 0, SEEK_SET), 0);144  ASSERT_EQ(LIBC_NAMESPACE::fread(data, 1, sizeof(CONTENT), file),145            sizeof(CONTENT));146  ASSERT_STREQ(data, CONTENT);147 148  ASSERT_EQ(LIBC_NAMESPACE::fclose(file), 0);149}150 151TEST_F(LlvmLibcFILETest, FOpenFWriteSizeGreaterThanOne) {152  using MyStruct = struct {153    char c;154    unsigned long long i;155  };156  constexpr MyStruct WRITE_DATA[] = {{'a', 1}, {'b', 2}, {'c', 3}};157  constexpr size_t WRITE_NMEMB = sizeof(WRITE_DATA) / sizeof(MyStruct);158  constexpr char FILENAME[] = APPEND_LIBC_TEST("testdata/fread_fwrite.test");159 160  FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w");161  ASSERT_FALSE(file == nullptr);162  ASSERT_EQ(size_t(0), LIBC_NAMESPACE::fwrite(WRITE_DATA, 0, 1, file));163  ASSERT_THAT(164      LIBC_NAMESPACE::fwrite(WRITE_DATA, sizeof(MyStruct), WRITE_NMEMB, file),165      returns(EQ(WRITE_NMEMB)).with_errno(EQ(0)));166  ASSERT_EQ(LIBC_NAMESPACE::fclose(file), 0);167 168  file = LIBC_NAMESPACE::fopen(FILENAME, "r");169  ASSERT_FALSE(file == nullptr);170  MyStruct read_data[WRITE_NMEMB];171  ASSERT_EQ(size_t(0), LIBC_NAMESPACE::fread(read_data, 0, 1, file));172  ASSERT_THAT(173      LIBC_NAMESPACE::fread(read_data, sizeof(MyStruct), WRITE_NMEMB, file),174      returns(EQ(WRITE_NMEMB)).with_errno(EQ(0)));175  // Trying to read more should fetch nothing.176  ASSERT_THAT(177      LIBC_NAMESPACE::fread(read_data, sizeof(MyStruct), WRITE_NMEMB, file),178      returns(EQ(size_t(0))).with_errno(EQ(0)));179  EXPECT_NE(LIBC_NAMESPACE::feof(file), 0);180  EXPECT_EQ(LIBC_NAMESPACE::ferror(file), 0);181  ASSERT_EQ(LIBC_NAMESPACE::fclose(file), 0);182  // Verify that the data which was read is correct.183  for (size_t i = 0; i < WRITE_NMEMB; ++i) {184    ASSERT_EQ(read_data[i].c, WRITE_DATA[i].c);185    ASSERT_EQ(read_data[i].i, WRITE_DATA[i].i);186  }187}188