1 : // Copyright 2012 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 : //
15 : // Declares some unittest helper functions.
16 :
17 : #ifndef SYZYGY_CORE_UNITTEST_UTIL_H_
18 : #define SYZYGY_CORE_UNITTEST_UTIL_H_
19 :
20 : #include "base/files/file_path.h"
21 : #include "base/files/file_util.h"
22 : #include "gtest/gtest.h"
23 : #include "syzygy/core/serialization.h"
24 :
25 : namespace testing {
26 :
27 : // Examples of the various file types that GuessFileType recognizes. These live
28 : // in syzygy\core\test_data, thus should be referred to using
29 : // GetSrcRelativePath.
30 : extern const wchar_t kExampleArchiveName[];
31 : extern const wchar_t kExampleCoff[];
32 : extern const wchar_t kExampleCoffImportDefinition[];
33 : extern const wchar_t kExampleCoffLtcgName[];
34 : extern const wchar_t kExampleCoffMachineTypeNullName[];
35 : extern const wchar_t kExamplePdbName[];
36 : extern const wchar_t kExamplePeDll[];
37 : extern const wchar_t kExamplePeExe[];
38 : extern const wchar_t kExampleResources32Name[];
39 :
40 : // A simple utility class for creating and cleaning up a temporary file.
41 : class ScopedTempFile {
42 : public:
43 E : ScopedTempFile() {
44 E : base::CreateTemporaryFile(&path_);
45 E : }
46 :
47 E : ~ScopedTempFile() {
48 E : base::DeleteFile(path_, false);
49 E : }
50 :
51 E : const base::FilePath& path() const { return path_; }
52 :
53 : private:
54 : base::FilePath path_;
55 : };
56 :
57 : // This defines a simple test of serialization for a given object. Returns
58 : // true on success, false otherwise. The data object must be default
59 : // constructible and comparable.
60 E : template<class Data> bool TestSerialization(const Data& data) {
61 E : core::ByteVector bytes;
62 :
63 E : core::ScopedOutStreamPtr out_stream;
64 E : out_stream.reset(core::CreateByteOutStream(std::back_inserter(bytes)));
65 E : core::NativeBinaryOutArchive out_archive(out_stream.get());
66 E : if (!out_archive.Save(data))
67 i : return false;
68 E : if (!out_archive.Flush())
69 i : return false;
70 :
71 E : core::ScopedInStreamPtr in_stream;
72 E : in_stream.reset(core::CreateByteInStream(bytes.begin(), bytes.end()));
73 E : core::NativeBinaryInArchive in_archive(in_stream.get());
74 E : Data data_copy;
75 E : if (!in_archive.Load(&data_copy))
76 i : return false;
77 :
78 : // Ensure the two elements are the same after a roundtrip through the
79 : // serialization engine.
80 E : return (data == data_copy);
81 E : }
82 :
83 : // Same as above, but serializes to the given file, which has to be opened
84 : // in read-write mode.
85 E : template<class Data> bool TestSerialization(const Data& data, FILE* file) {
86 E : core::FileOutStream out_stream(file);
87 E : core::NativeBinaryOutArchive out_archive(&out_stream);
88 E : if (!out_archive.Save(data))
89 i : return false;
90 :
91 : // Flush the output and rewind the file.
92 E : fflush(file);
93 E : fseek(file, 0, SEEK_SET);
94 :
95 E : core::FileInStream in_stream(file);
96 E : core::NativeBinaryInArchive in_archive(&in_stream);
97 E : Data data_copy;
98 E : if (!in_archive.Load(&data_copy))
99 i : return false;
100 :
101 : // Ensure the two elements are the same after a roundtrip through the
102 : // serialization engine.
103 E : return (data == data_copy);
104 E : }
105 :
106 : // Converts a relative path to absolute using the src directory as base.
107 : //
108 : // @path rel_path the relative path to convert.
109 : // @returns an absolute path.
110 : base::FilePath GetSrcRelativePath(const wchar_t* rel_path);
111 :
112 : // Converts a relative path to absolute using the executable directory as base.
113 : //
114 : // @path rel_path the relative path to convert.
115 : // @returns an absolute path.
116 : base::FilePath GetExeRelativePath(const wchar_t* rel_path);
117 :
118 : // Converts a relative path to absolute using the output directory as base.
119 : //
120 : // @path rel_path the relative path to convert.
121 : // @returns an absolute path.
122 : base::FilePath GetOutputRelativePath(const wchar_t* rel_path);
123 :
124 : // Converts a relative path to absolute using the test_data directory as base.
125 : //
126 : // @path rel_path the relative path to convert.
127 : // @returns an absolute path.
128 : base::FilePath GetExeTestDataRelativePath(const wchar_t* rel_path);
129 :
130 : // Converts an absolute path to a relative path using the given root directory
131 : // as a base.
132 : //
133 : // @param abs_path the absolute path to convert.
134 : // @param root_path the root path to use.
135 : // @returns the relative path to abs_path, starting from root. If there is no
136 : // relative path, it returns the empty path.
137 : // @pre Both abs_path and root_path must be absolute paths.
138 : base::FilePath GetRelativePath(const base::FilePath& abs_path,
139 : const base::FilePath& root_path);
140 :
141 : // Converts an absolute path to a relative path using the current working
142 : // directory as a base.
143 : //
144 : // @param abs_path the absolute path to convert.
145 : // @returns the relative path to abs_path, starting from the current working
146 : // directory. If there is no relative path, it returns the empty path.
147 : base::FilePath GetRelativePath(const base::FilePath& abs_path);
148 :
149 : // A utility for ensuring that two file paths point to the same file. Upon
150 : // failure, outputs the actual paths as well. This is not intended to be used
151 : // directly, but rather through the ASSERT_SAME_FILE and EXPECT_SAME_FILE
152 : // macros.
153 : // @param path1_expr the source code expression representing the contents of
154 : // path1.
155 : // @param path2_expr the source code expression representing the contents of
156 : // path2.
157 : // @param path1 the first path to compare.
158 : // @param path2 the second path to compare.
159 : // @returns AssertionSuccess if path1 and path2 refer to the same file on disk,
160 : // even if they have different paths. Otherwise, returns an AssertionFailure
161 : // with an informative error message.
162 : AssertionResult AssertAreSameFile(const char* path1_expr,
163 : const char* path2_expr,
164 : const base::FilePath& path1,
165 : const base::FilePath& path2);
166 :
167 : // GTest macros for ensuring two paths refer to the same file.
168 : #define ASSERT_SAME_FILE(path1, path2) \
169 : ASSERT_PRED_FORMAT2(::testing::AssertAreSameFile, path1, path2)
170 : #define EXPECT_SAME_FILE(path1, path2) \
171 : EXPECT_PRED_FORMAT2(::testing::AssertAreSameFile, path1, path2)
172 :
173 : } // namespace testing
174 :
175 : #endif // SYZYGY_CORE_UNITTEST_UTIL_H_
|