1cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert/*
2cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * Copyright (C) 2015 The Android Open Source Project
3cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert *
4cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * Licensed under the Apache License, Version 2.0 (the "License");
5cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * you may not use this file except in compliance with the License.
6cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * You may obtain a copy of the License at
7cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert *
8cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert *      http://www.apache.org/licenses/LICENSE-2.0
9cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert *
10cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * Unless required by applicable law or agreed to in writing, software
11cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * distributed under the License is distributed on an "AS IS" BASIS,
12cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * See the License for the specific language governing permissions and
14cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * limitations under the License.
15cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert */
16cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
17cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert#include "adb_io.h"
18cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
19cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert#include <gtest/gtest.h>
20cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
2108f66bc771ac798d89451a9b68a1c6722352d683Dan Albert#include <fcntl.h>
22cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert#include <stdio.h>
23cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert#include <stdlib.h>
2408f66bc771ac798d89451a9b68a1c6722352d683Dan Albert#include <sys/stat.h>
2508f66bc771ac798d89451a9b68a1c6722352d683Dan Albert#include <sys/types.h>
26cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert#include <unistd.h>
27cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
28cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert#include <string>
29cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
304f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/file.h>
314f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/test_utils.h>
32cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
33cf168a82e99e97e3ad95e37b7065f6b8e7f7390bSpencer Low// All of these tests fail on Windows because they use the C Runtime open(),
342fbeb0cc713f47ec699bfed4bc530aa19e08e1a3Spencer Low// but the adb_io APIs expect file descriptors from adb_open(). This could
352fbeb0cc713f47ec699bfed4bc530aa19e08e1a3Spencer Low// theoretically be fixed by making adb_read()/adb_write() fallback to using
362fbeb0cc713f47ec699bfed4bc530aa19e08e1a3Spencer Low// read()/write() if an unrecognized fd is used, and by making adb_open() return
372fbeb0cc713f47ec699bfed4bc530aa19e08e1a3Spencer Low// fds far from the range that open() returns. But all of that might defeat the
382fbeb0cc713f47ec699bfed4bc530aa19e08e1a3Spencer Low// purpose of the tests.
39cf168a82e99e97e3ad95e37b7065f6b8e7f7390bSpencer Low
40cc731cc76786b6bdc58764aad9924c0d0c8d645fDan AlbertTEST(io, ReadFdExactly_whole) {
41cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  const char expected[] = "Foobar";
42cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  TemporaryFile tf;
43cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  ASSERT_NE(-1, tf.fd);
44cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
45c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert  ASSERT_TRUE(android::base::WriteStringToFd(expected, tf.fd)) << strerror(errno);
46c96de0d36eb2954be0d5009d72f965e805d58f23Elliott Hughes  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));
47cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
48cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  // Test reading the whole file.
49cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  char buf[sizeof(expected)] = {};
50cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  ASSERT_TRUE(ReadFdExactly(tf.fd, buf, sizeof(buf) - 1)) << strerror(errno);
51cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  EXPECT_STREQ(expected, buf);
52cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert}
53cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
54cc731cc76786b6bdc58764aad9924c0d0c8d645fDan AlbertTEST(io, ReadFdExactly_eof) {
55cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  const char expected[] = "Foobar";
56cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  TemporaryFile tf;
57cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  ASSERT_NE(-1, tf.fd);
58cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
59c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert  ASSERT_TRUE(android::base::WriteStringToFd(expected, tf.fd)) << strerror(errno);
60c96de0d36eb2954be0d5009d72f965e805d58f23Elliott Hughes  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));
61cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
62cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  // Test that not having enough data will fail.
63cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  char buf[sizeof(expected) + 1] = {};
64cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  ASSERT_FALSE(ReadFdExactly(tf.fd, buf, sizeof(buf)));
65cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  EXPECT_EQ(0, errno) << strerror(errno);
66cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert}
67cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
68cc731cc76786b6bdc58764aad9924c0d0c8d645fDan AlbertTEST(io, ReadFdExactly_partial) {
69cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  const char input[] = "Foobar";
70cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  TemporaryFile tf;
71cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  ASSERT_NE(-1, tf.fd);
72cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
73c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert  ASSERT_TRUE(android::base::WriteStringToFd(input, tf.fd)) << strerror(errno);
74c96de0d36eb2954be0d5009d72f965e805d58f23Elliott Hughes  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));
75cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
76cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  // Test reading a partial file.
77cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  char buf[sizeof(input) - 1] = {};
78cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  ASSERT_TRUE(ReadFdExactly(tf.fd, buf, sizeof(buf) - 1));
79cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
80cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  std::string expected(input);
81cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  expected.pop_back();
82cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  EXPECT_STREQ(expected.c_str(), buf);
83cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert}
84cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
85cc731cc76786b6bdc58764aad9924c0d0c8d645fDan AlbertTEST(io, WriteFdExactly_whole) {
86cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  const char expected[] = "Foobar";
87cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  TemporaryFile tf;
88cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  ASSERT_NE(-1, tf.fd);
89cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
90cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  // Test writing the whole string to the file.
91cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  ASSERT_TRUE(WriteFdExactly(tf.fd, expected, sizeof(expected)))
92cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    << strerror(errno);
93c96de0d36eb2954be0d5009d72f965e805d58f23Elliott Hughes  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));
94cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
95cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  std::string s;
96c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert  ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s));
97cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  EXPECT_STREQ(expected, s.c_str());
98cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert}
99cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
100cc731cc76786b6bdc58764aad9924c0d0c8d645fDan AlbertTEST(io, WriteFdExactly_partial) {
101cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  const char buf[] = "Foobar";
102cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  TemporaryFile tf;
103cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  ASSERT_NE(-1, tf.fd);
104cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
105cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  // Test writing a partial string to the file.
106cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  ASSERT_TRUE(WriteFdExactly(tf.fd, buf, sizeof(buf) - 2)) << strerror(errno);
107c96de0d36eb2954be0d5009d72f965e805d58f23Elliott Hughes  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));
108cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
109cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  std::string expected(buf);
110cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  expected.pop_back();
111cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
112cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  std::string s;
113c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert  ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s));
114cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  EXPECT_EQ(expected, s);
115cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert}
116cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
11708f66bc771ac798d89451a9b68a1c6722352d683Dan AlbertTEST(io, WriteFdExactly_ENOSPC) {
11808f66bc771ac798d89451a9b68a1c6722352d683Dan Albert    int fd = open("/dev/full", O_WRONLY);
11908f66bc771ac798d89451a9b68a1c6722352d683Dan Albert    ASSERT_NE(-1, fd);
12008f66bc771ac798d89451a9b68a1c6722352d683Dan Albert
12108f66bc771ac798d89451a9b68a1c6722352d683Dan Albert    char buf[] = "foo";
12208f66bc771ac798d89451a9b68a1c6722352d683Dan Albert    ASSERT_FALSE(WriteFdExactly(fd, buf, sizeof(buf)));
12308f66bc771ac798d89451a9b68a1c6722352d683Dan Albert    ASSERT_EQ(ENOSPC, errno);
12408f66bc771ac798d89451a9b68a1c6722352d683Dan Albert}
12508f66bc771ac798d89451a9b68a1c6722352d683Dan Albert
126e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott HughesTEST(io, WriteFdExactly_string) {
127cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  const char str[] = "Foobar";
128cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  TemporaryFile tf;
129cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  ASSERT_NE(-1, tf.fd);
130cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
131cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  // Test writing a partial string to the file.
132e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes  ASSERT_TRUE(WriteFdExactly(tf.fd, str)) << strerror(errno);
133c96de0d36eb2954be0d5009d72f965e805d58f23Elliott Hughes  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));
134cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
135cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  std::string s;
136c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert  ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s));
137cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert  EXPECT_STREQ(str, s.c_str());
138cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert}
139ab52c181fa4c1c9891644635dc5653cda5b90e2bElliott Hughes
140ab52c181fa4c1c9891644635dc5653cda5b90e2bElliott HughesTEST(io, WriteFdFmt) {
141ab52c181fa4c1c9891644635dc5653cda5b90e2bElliott Hughes    TemporaryFile tf;
142ab52c181fa4c1c9891644635dc5653cda5b90e2bElliott Hughes    ASSERT_NE(-1, tf.fd);
143ab52c181fa4c1c9891644635dc5653cda5b90e2bElliott Hughes
144ab52c181fa4c1c9891644635dc5653cda5b90e2bElliott Hughes    // Test writing a partial string to the file.
145ab52c181fa4c1c9891644635dc5653cda5b90e2bElliott Hughes    ASSERT_TRUE(WriteFdFmt(tf.fd, "Foo%s%d", "bar", 123)) << strerror(errno);
146c96de0d36eb2954be0d5009d72f965e805d58f23Elliott Hughes    ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));
147ab52c181fa4c1c9891644635dc5653cda5b90e2bElliott Hughes
148ab52c181fa4c1c9891644635dc5653cda5b90e2bElliott Hughes    std::string s;
149ab52c181fa4c1c9891644635dc5653cda5b90e2bElliott Hughes    ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s));
150ab52c181fa4c1c9891644635dc5653cda5b90e2bElliott Hughes    EXPECT_STREQ("Foobar123", s.c_str());
151ab52c181fa4c1c9891644635dc5653cda5b90e2bElliott Hughes}
152