1// Copyright (c) 2009, Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8//     * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10//     * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14//     * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30#include <stdlib.h>
31#include <unistd.h>
32#include <sys/types.h>
33
34#include "client/linux/minidump_writer/line_reader.h"
35#include "breakpad_googletest_includes.h"
36#include "common/linux/tests/auto_testfile.h"
37
38using namespace google_breakpad;
39
40namespace {
41
42typedef testing::Test LineReaderTest;
43
44class ScopedTestFile : public AutoTestFile {
45public:
46  explicit ScopedTestFile(const char* text)
47    : AutoTestFile("line_reader", text) {
48  }
49
50  ScopedTestFile(const char* text, size_t text_len)
51    : AutoTestFile("line_reader", text, text_len) {
52  }
53};
54
55}
56
57TEST(LineReaderTest, EmptyFile) {
58  ScopedTestFile file("");
59  ASSERT_TRUE(file.IsOk());
60  LineReader reader(file.GetFd());
61
62  const char *line;
63  unsigned len;
64  ASSERT_FALSE(reader.GetNextLine(&line, &len));
65}
66
67TEST(LineReaderTest, OneLineTerminated) {
68  ScopedTestFile file("a\n");
69  ASSERT_TRUE(file.IsOk());
70  LineReader reader(file.GetFd());
71
72  const char *line;
73  unsigned int len;
74  ASSERT_TRUE(reader.GetNextLine(&line, &len));
75  ASSERT_EQ((unsigned int)1, len);
76  ASSERT_EQ('a', line[0]);
77  ASSERT_EQ('\0', line[1]);
78  reader.PopLine(len);
79
80  ASSERT_FALSE(reader.GetNextLine(&line, &len));
81}
82
83TEST(LineReaderTest, OneLine) {
84  ScopedTestFile file("a");
85  ASSERT_TRUE(file.IsOk());
86  LineReader reader(file.GetFd());
87
88  const char *line;
89  unsigned len;
90  ASSERT_TRUE(reader.GetNextLine(&line, &len));
91  ASSERT_EQ((unsigned)1, len);
92  ASSERT_EQ('a', line[0]);
93  ASSERT_EQ('\0', line[1]);
94  reader.PopLine(len);
95
96  ASSERT_FALSE(reader.GetNextLine(&line, &len));
97}
98
99TEST(LineReaderTest, TwoLinesTerminated) {
100  ScopedTestFile file("a\nb\n");
101  ASSERT_TRUE(file.IsOk());
102  LineReader reader(file.GetFd());
103
104  const char *line;
105  unsigned len;
106  ASSERT_TRUE(reader.GetNextLine(&line, &len));
107  ASSERT_EQ((unsigned)1, len);
108  ASSERT_EQ('a', line[0]);
109  ASSERT_EQ('\0', line[1]);
110  reader.PopLine(len);
111
112  ASSERT_TRUE(reader.GetNextLine(&line, &len));
113  ASSERT_EQ((unsigned)1, len);
114  ASSERT_EQ('b', line[0]);
115  ASSERT_EQ('\0', line[1]);
116  reader.PopLine(len);
117
118  ASSERT_FALSE(reader.GetNextLine(&line, &len));
119}
120
121TEST(LineReaderTest, TwoLines) {
122  ScopedTestFile file("a\nb");
123  ASSERT_TRUE(file.IsOk());
124  LineReader reader(file.GetFd());
125
126  const char *line;
127  unsigned len;
128  ASSERT_TRUE(reader.GetNextLine(&line, &len));
129  ASSERT_EQ((unsigned)1, len);
130  ASSERT_EQ('a', line[0]);
131  ASSERT_EQ('\0', line[1]);
132  reader.PopLine(len);
133
134  ASSERT_TRUE(reader.GetNextLine(&line, &len));
135  ASSERT_EQ((unsigned)1, len);
136  ASSERT_EQ('b', line[0]);
137  ASSERT_EQ('\0', line[1]);
138  reader.PopLine(len);
139
140  ASSERT_FALSE(reader.GetNextLine(&line, &len));
141}
142
143TEST(LineReaderTest, MaxLength) {
144  char l[LineReader::kMaxLineLen-1];
145  memset(l, 'a', sizeof(l));
146  ScopedTestFile file(l, sizeof(l));
147  ASSERT_TRUE(file.IsOk());
148  LineReader reader(file.GetFd());
149
150  const char *line;
151  unsigned len;
152  ASSERT_TRUE(reader.GetNextLine(&line, &len));
153  ASSERT_EQ(sizeof(l), len);
154  ASSERT_TRUE(memcmp(l, line, sizeof(l)) == 0);
155  ASSERT_EQ('\0', line[len]);
156}
157
158TEST(LineReaderTest, TooLong) {
159  // Note: this writes kMaxLineLen 'a' chars in the test file.
160  char l[LineReader::kMaxLineLen];
161  memset(l, 'a', sizeof(l));
162  ScopedTestFile file(l, sizeof(l));
163  ASSERT_TRUE(file.IsOk());
164  LineReader reader(file.GetFd());
165
166  const char *line;
167  unsigned len;
168  ASSERT_FALSE(reader.GetNextLine(&line, &len));
169}
170