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