1 // Copyright (c) 2013, 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 #include <stdio.h>
34 #include <errno.h>
35 #include <string.h>
36
37 #include "client/linux/minidump_writer/proc_cpuinfo_reader.h"
38 #include "breakpad_googletest_includes.h"
39 #include "common/linux/tests/auto_testfile.h"
40
41 using namespace google_breakpad;
42
43 #if !defined(__ANDROID__)
44 #define TEMPDIR "/tmp"
45 #else
46 #define TEMPDIR "/data/local/tmp"
47 #endif
48
49
50 namespace {
51
52 typedef testing::Test ProcCpuInfoReaderTest;
53
54 class ScopedTestFile : public AutoTestFile {
55 public:
ScopedTestFile(const char * text)56 explicit ScopedTestFile(const char* text)
57 : AutoTestFile("proc_cpuinfo_reader", text) {
58 }
59 };
60
61 }
62
TEST(ProcCpuInfoReaderTest,EmptyFile)63 TEST(ProcCpuInfoReaderTest, EmptyFile) {
64 ScopedTestFile file("");
65 ASSERT_TRUE(file.IsOk());
66 ProcCpuInfoReader reader(file.GetFd());
67
68 const char *field;
69 ASSERT_FALSE(reader.GetNextField(&field));
70 }
71
TEST(ProcCpuInfoReaderTest,OneLineTerminated)72 TEST(ProcCpuInfoReaderTest, OneLineTerminated) {
73 ScopedTestFile file("foo : bar\n");
74 ASSERT_TRUE(file.IsOk());
75 ProcCpuInfoReader reader(file.GetFd());
76
77 const char *field;
78 ASSERT_TRUE(reader.GetNextField(&field));
79 ASSERT_STREQ("foo", field);
80 ASSERT_STREQ("bar", reader.GetValue());
81
82 ASSERT_FALSE(reader.GetNextField(&field));
83 }
84
TEST(ProcCpuInfoReaderTest,OneLine)85 TEST(ProcCpuInfoReaderTest, OneLine) {
86 ScopedTestFile file("foo : bar");
87 ASSERT_TRUE(file.IsOk());
88 ProcCpuInfoReader reader(file.GetFd());
89
90 const char *field;
91 size_t value_len;
92 ASSERT_TRUE(reader.GetNextField(&field));
93 ASSERT_STREQ("foo", field);
94 ASSERT_STREQ("bar", reader.GetValueAndLen(&value_len));
95 ASSERT_EQ(3U, value_len);
96
97 ASSERT_FALSE(reader.GetNextField(&field));
98 }
99
TEST(ProcCpuInfoReaderTest,TwoLinesTerminated)100 TEST(ProcCpuInfoReaderTest, TwoLinesTerminated) {
101 ScopedTestFile file("foo : bar\nzoo : tut\n");
102 ASSERT_TRUE(file.IsOk());
103 ProcCpuInfoReader reader(file.GetFd());
104
105 const char* field;
106 ASSERT_TRUE(reader.GetNextField(&field));
107 ASSERT_STREQ("foo", field);
108 ASSERT_STREQ("bar", reader.GetValue());
109
110 ASSERT_TRUE(reader.GetNextField(&field));
111 ASSERT_STREQ("zoo", field);
112 ASSERT_STREQ("tut", reader.GetValue());
113
114 ASSERT_FALSE(reader.GetNextField(&field));
115 }
116
TEST(ProcCpuInfoReaderTest,SkipMalformedLine)117 TEST(ProcCpuInfoReaderTest, SkipMalformedLine) {
118 ScopedTestFile file("this line should have a column\nfoo : bar\n");
119 ASSERT_TRUE(file.IsOk());
120 ProcCpuInfoReader reader(file.GetFd());
121
122 const char* field;
123 ASSERT_TRUE(reader.GetNextField(&field));
124 ASSERT_STREQ("foo", field);
125 ASSERT_STREQ("bar", reader.GetValue());
126
127 ASSERT_FALSE(reader.GetNextField(&field));
128 }
129
TEST(ProcCpuInfoReaderTest,SkipOneEmptyLine)130 TEST(ProcCpuInfoReaderTest, SkipOneEmptyLine) {
131 ScopedTestFile file("\n\nfoo : bar\n");
132 ASSERT_TRUE(file.IsOk());
133 ProcCpuInfoReader reader(file.GetFd());
134
135 const char* field;
136 ASSERT_TRUE(reader.GetNextField(&field));
137 ASSERT_STREQ("foo", field);
138 ASSERT_STREQ("bar", reader.GetValue());
139
140 ASSERT_FALSE(reader.GetNextField(&field));
141 }
142
TEST(ProcCpuInfoReaderTest,SkipEmptyField)143 TEST(ProcCpuInfoReaderTest, SkipEmptyField) {
144 ScopedTestFile file(" : bar\nzoo : tut\n");
145 ASSERT_TRUE(file.IsOk());
146 ProcCpuInfoReader reader(file.GetFd());
147
148 const char* field;
149 ASSERT_TRUE(reader.GetNextField(&field));
150 ASSERT_STREQ("zoo", field);
151 ASSERT_STREQ("tut", reader.GetValue());
152
153 ASSERT_FALSE(reader.GetNextField(&field));
154 }
155
TEST(ProcCpuInfoReaderTest,SkipTwoEmptyLines)156 TEST(ProcCpuInfoReaderTest, SkipTwoEmptyLines) {
157 ScopedTestFile file("foo : bar\n\n\nfoo : bar\n");
158 ASSERT_TRUE(file.IsOk());
159 ProcCpuInfoReader reader(file.GetFd());
160
161 const char* field;
162 ASSERT_TRUE(reader.GetNextField(&field));
163 ASSERT_STREQ("foo", field);
164 ASSERT_STREQ("bar", reader.GetValue());
165
166 ASSERT_TRUE(reader.GetNextField(&field));
167 ASSERT_STREQ("foo", field);
168 ASSERT_STREQ("bar", reader.GetValue());
169
170 ASSERT_FALSE(reader.GetNextField(&field));
171 }
172
TEST(ProcCpuInfoReaderTest,FieldWithSpaces)173 TEST(ProcCpuInfoReaderTest, FieldWithSpaces) {
174 ScopedTestFile file("foo bar : zoo\n");
175 ASSERT_TRUE(file.IsOk());
176 ProcCpuInfoReader reader(file.GetFd());
177
178 const char* field;
179 ASSERT_TRUE(reader.GetNextField(&field));
180 ASSERT_STREQ("foo bar", field);
181 ASSERT_STREQ("zoo", reader.GetValue());
182
183 ASSERT_FALSE(reader.GetNextField(&field));
184 }
185
TEST(ProcCpuInfoReaderTest,EmptyValue)186 TEST(ProcCpuInfoReaderTest, EmptyValue) {
187 ScopedTestFile file("foo :\n");
188 ASSERT_TRUE(file.IsOk());
189 ProcCpuInfoReader reader(file.GetFd());
190
191 const char* field;
192 ASSERT_TRUE(reader.GetNextField(&field));
193 ASSERT_STREQ("foo", field);
194 size_t value_len;
195 ASSERT_STREQ("", reader.GetValueAndLen(&value_len));
196 ASSERT_EQ(0U, value_len);
197
198 ASSERT_FALSE(reader.GetNextField(&field));
199 }
200