Home | History | Annotate | Download | only in adb
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "adb_io.h"
     18 
     19 #include <gtest/gtest.h>
     20 
     21 #include <fcntl.h>
     22 #include <stdio.h>
     23 #include <stdlib.h>
     24 #include <sys/stat.h>
     25 #include <sys/types.h>
     26 #include <unistd.h>
     27 
     28 #include <string>
     29 
     30 #include "base/file.h"
     31 
     32 class TemporaryFile {
     33  public:
     34   TemporaryFile() {
     35     init("/data/local/tmp");
     36     if (fd == -1) {
     37       init("/tmp");
     38     }
     39   }
     40 
     41   ~TemporaryFile() {
     42     close(fd);
     43     unlink(filename);
     44   }
     45 
     46   int fd;
     47   char filename[1024];
     48 
     49  private:
     50   void init(const char* tmp_dir) {
     51     snprintf(filename, sizeof(filename), "%s/TemporaryFile-XXXXXX", tmp_dir);
     52     fd = mkstemp(filename);
     53   }
     54 };
     55 
     56 TEST(io, ReadFdExactly_whole) {
     57   const char expected[] = "Foobar";
     58   TemporaryFile tf;
     59   ASSERT_NE(-1, tf.fd);
     60 
     61   ASSERT_TRUE(android::base::WriteStringToFd(expected, tf.fd)) << strerror(errno);
     62   ASSERT_EQ(0, lseek(tf.fd, SEEK_SET, 0));
     63 
     64   // Test reading the whole file.
     65   char buf[sizeof(expected)] = {};
     66   ASSERT_TRUE(ReadFdExactly(tf.fd, buf, sizeof(buf) - 1)) << strerror(errno);
     67   EXPECT_STREQ(expected, buf);
     68 }
     69 
     70 TEST(io, ReadFdExactly_eof) {
     71   const char expected[] = "Foobar";
     72   TemporaryFile tf;
     73   ASSERT_NE(-1, tf.fd);
     74 
     75   ASSERT_TRUE(android::base::WriteStringToFd(expected, tf.fd)) << strerror(errno);
     76   ASSERT_EQ(0, lseek(tf.fd, SEEK_SET, 0));
     77 
     78   // Test that not having enough data will fail.
     79   char buf[sizeof(expected) + 1] = {};
     80   ASSERT_FALSE(ReadFdExactly(tf.fd, buf, sizeof(buf)));
     81   EXPECT_EQ(0, errno) << strerror(errno);
     82 }
     83 
     84 TEST(io, ReadFdExactly_partial) {
     85   const char input[] = "Foobar";
     86   TemporaryFile tf;
     87   ASSERT_NE(-1, tf.fd);
     88 
     89   ASSERT_TRUE(android::base::WriteStringToFd(input, tf.fd)) << strerror(errno);
     90   ASSERT_EQ(0, lseek(tf.fd, SEEK_SET, 0));
     91 
     92   // Test reading a partial file.
     93   char buf[sizeof(input) - 1] = {};
     94   ASSERT_TRUE(ReadFdExactly(tf.fd, buf, sizeof(buf) - 1));
     95 
     96   std::string expected(input);
     97   expected.pop_back();
     98   EXPECT_STREQ(expected.c_str(), buf);
     99 }
    100 
    101 TEST(io, WriteFdExactly_whole) {
    102   const char expected[] = "Foobar";
    103   TemporaryFile tf;
    104   ASSERT_NE(-1, tf.fd);
    105 
    106   // Test writing the whole string to the file.
    107   ASSERT_TRUE(WriteFdExactly(tf.fd, expected, sizeof(expected)))
    108     << strerror(errno);
    109   ASSERT_EQ(0, lseek(tf.fd, SEEK_SET, 0));
    110 
    111   std::string s;
    112   ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s));
    113   EXPECT_STREQ(expected, s.c_str());
    114 }
    115 
    116 TEST(io, WriteFdExactly_partial) {
    117   const char buf[] = "Foobar";
    118   TemporaryFile tf;
    119   ASSERT_NE(-1, tf.fd);
    120 
    121   // Test writing a partial string to the file.
    122   ASSERT_TRUE(WriteFdExactly(tf.fd, buf, sizeof(buf) - 2)) << strerror(errno);
    123   ASSERT_EQ(0, lseek(tf.fd, SEEK_SET, 0));
    124 
    125   std::string expected(buf);
    126   expected.pop_back();
    127 
    128   std::string s;
    129   ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s));
    130   EXPECT_EQ(expected, s);
    131 }
    132 
    133 TEST(io, WriteFdExactly_ENOSPC) {
    134     int fd = open("/dev/full", O_WRONLY);
    135     ASSERT_NE(-1, fd);
    136 
    137     char buf[] = "foo";
    138     ASSERT_FALSE(WriteFdExactly(fd, buf, sizeof(buf)));
    139     ASSERT_EQ(ENOSPC, errno);
    140 }
    141 
    142 TEST(io, WriteFdExactly_string) {
    143   const char str[] = "Foobar";
    144   TemporaryFile tf;
    145   ASSERT_NE(-1, tf.fd);
    146 
    147   // Test writing a partial string to the file.
    148   ASSERT_TRUE(WriteFdExactly(tf.fd, str)) << strerror(errno);
    149   ASSERT_EQ(0, lseek(tf.fd, SEEK_SET, 0));
    150 
    151   std::string s;
    152   ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s));
    153   EXPECT_STREQ(str, s.c_str());
    154 }
    155 
    156 TEST(io, WriteFdFmt) {
    157     TemporaryFile tf;
    158     ASSERT_NE(-1, tf.fd);
    159 
    160     // Test writing a partial string to the file.
    161     ASSERT_TRUE(WriteFdFmt(tf.fd, "Foo%s%d", "bar", 123)) << strerror(errno);
    162     ASSERT_EQ(0, lseek(tf.fd, SEEK_SET, 0));
    163 
    164     std::string s;
    165     ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s));
    166     EXPECT_STREQ("Foobar123", s.c_str());
    167 }
    168