1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <dirent.h>
6#include <errno.h>
7#include <fcntl.h>
8#include <limits.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <sys/stat.h>
12#include <unistd.h>
13
14#include <fbl/auto_call.h>
15#include <fbl/string.h>
16#include <fbl/string_buffer.h>
17#include <fbl/unique_fd.h>
18#include <fbl/unique_ptr.h>
19#include <fbl/vector.h>
20#include <runtests-utils/fuchsia-run-test.h>
21#include <runtests-utils/runtests-utils.h>
22#include <unittest/unittest.h>
23
24#include "runtests-utils-test-globals.h"
25#include "runtests-utils-test-utils.h"
26
27namespace runtests {
28namespace {
29
30bool TestFileComponentInfoTest() {
31    BEGIN_TEST;
32    fbl::String component_url;
33    fbl::String cmx_file_path;
34
35    component_url = "";
36    cmx_file_path = "";
37    TestFileComponentInfo("", &component_url, &cmx_file_path);
38    EXPECT_STR_EQ("", component_url.c_str());
39    EXPECT_STR_EQ("", cmx_file_path.c_str());
40
41    component_url = "";
42    cmx_file_path = "";
43    TestFileComponentInfo("/", &component_url, &cmx_file_path);
44    EXPECT_STR_EQ("", component_url.c_str());
45    EXPECT_STR_EQ("", cmx_file_path.c_str());
46
47    component_url = "";
48    cmx_file_path = "";
49    TestFileComponentInfo("/system/test", &component_url, &cmx_file_path);
50    EXPECT_STR_EQ("", component_url.c_str());
51    EXPECT_STR_EQ("", cmx_file_path.c_str());
52
53    component_url = "";
54    cmx_file_path = "";
55    TestFileComponentInfo("/pkgfs", &component_url, &cmx_file_path);
56    EXPECT_STR_EQ("", component_url.c_str());
57    EXPECT_STR_EQ("", cmx_file_path.c_str());
58
59    component_url = "";
60    cmx_file_path = "";
61    TestFileComponentInfo("/pkgfs/packages", &component_url, &cmx_file_path);
62    EXPECT_STR_EQ("", component_url.c_str());
63    EXPECT_STR_EQ("", cmx_file_path.c_str());
64
65    component_url = "";
66    cmx_file_path = "";
67    TestFileComponentInfo("/pkgfs/packages/", &component_url,
68                          &cmx_file_path);
69    EXPECT_STR_EQ("", component_url.c_str());
70    EXPECT_STR_EQ("", cmx_file_path.c_str());
71
72    component_url = "";
73    cmx_file_path = "";
74    TestFileComponentInfo("/pkgfs/packages/foo", &component_url,
75                          &cmx_file_path);
76    EXPECT_STR_EQ("", component_url.c_str());
77    EXPECT_STR_EQ("", cmx_file_path.c_str());
78
79    component_url = "";
80    cmx_file_path = "";
81    TestFileComponentInfo("/pkgfs/packages/foo/", &component_url,
82                          &cmx_file_path);
83    EXPECT_STR_EQ("", component_url.c_str());
84    EXPECT_STR_EQ("", cmx_file_path.c_str());
85
86    component_url = "";
87    cmx_file_path = "";
88    TestFileComponentInfo("/pkgfs/packages/foo/bar", &component_url,
89                          &cmx_file_path);
90    EXPECT_STR_EQ("", component_url.c_str());
91    EXPECT_STR_EQ("", cmx_file_path.c_str());
92
93    component_url = "";
94    cmx_file_path = "";
95    TestFileComponentInfo("/pkgfs/packages/foo/bar/", &component_url,
96                          &cmx_file_path);
97    EXPECT_STR_EQ("", component_url.c_str());
98    EXPECT_STR_EQ("", cmx_file_path.c_str());
99
100    component_url = "";
101    cmx_file_path = "";
102    TestFileComponentInfo("/pkgfs/packages/pname/foo/bar/", &component_url,
103                          &cmx_file_path);
104    EXPECT_STR_EQ("fuchsia-pkg://fuchsia.com/pname#meta/bar.cmx",
105                  component_url.c_str());
106    EXPECT_STR_EQ("/pkgfs/packages/pname/meta/bar.cmx", cmx_file_path.c_str());
107
108    component_url = "";
109    cmx_file_path = "";
110    TestFileComponentInfo("/pkgfs/packages/pname/foo/bar/test_file",
111                          &component_url, &cmx_file_path);
112    EXPECT_STR_EQ("fuchsia-pkg://fuchsia.com/pname#meta/test_file.cmx",
113                  component_url.c_str());
114    EXPECT_STR_EQ("/pkgfs/packages/pname/foo/meta/test_file.cmx",
115                  cmx_file_path.c_str());
116
117    component_url = "";
118    cmx_file_path = "";
119    TestFileComponentInfo("/pkgfs/packages/pname/foo/bar/test/file",
120                          &component_url, &cmx_file_path);
121    EXPECT_STR_EQ("fuchsia-pkg://fuchsia.com/pname#meta/file.cmx",
122                  component_url.c_str());
123    EXPECT_STR_EQ("/pkgfs/packages/pname/foo/bar/meta/file.cmx",
124                  cmx_file_path.c_str());
125
126    component_url = "";
127    cmx_file_path = "";
128    TestFileComponentInfo("/pkgfs/packages/pname/foo/bar/test/file/",
129                          &component_url, &cmx_file_path);
130    EXPECT_STR_EQ("fuchsia-pkg://fuchsia.com/pname#meta/file.cmx",
131                  component_url.c_str());
132    EXPECT_STR_EQ("/pkgfs/packages/pname/foo/bar/meta/file.cmx",
133                  cmx_file_path.c_str());
134
135    component_url = "";
136    cmx_file_path = "";
137    TestFileComponentInfo("/pkgfs/packages/pname/0/test/disabled/test_name",
138                          &component_url, &cmx_file_path);
139    EXPECT_STR_EQ("fuchsia-pkg://fuchsia.com/pname#meta/test_name.cmx",
140                  component_url.c_str());
141    EXPECT_STR_EQ("/pkgfs/packages/pname/0/meta/test_name.cmx",
142                  cmx_file_path.c_str());
143
144    END_TEST;
145}
146
147bool RunTestDontPublishData() {
148    BEGIN_TEST;
149
150    ScopedTestDir test_dir;
151    fbl::String test_name = JoinPath(test_dir.path(), "publish-data-helper");
152    ScopedTestFile file(test_name.c_str(), "/boot/bin/publish-data-helper");
153
154    const char* argv[] = {test_name.c_str(), nullptr};
155    fbl::unique_ptr<Result> result = PlatformRunTest(argv, nullptr, nullptr);
156    EXPECT_STR_EQ(argv[0], result->name.c_str());
157    EXPECT_EQ(SUCCESS, result->launch_status);
158    EXPECT_EQ(0, result->return_code);
159    EXPECT_EQ(0, result->data_sinks.size());
160
161    END_TEST;
162}
163
164bool RunTestsPublishData() {
165    BEGIN_TEST;
166
167    ScopedTestDir test_dir;
168    fbl::String test_name = JoinPath(test_dir.path(), "publish-data-helper");
169    ScopedTestFile file(test_name.c_str(), "/boot/bin/publish-data-helper");
170    int num_failed = 0;
171    fbl::Vector<fbl::unique_ptr<Result>> results;
172    const signed char verbosity = 77;
173    const fbl::String output_dir = JoinPath(test_dir.path(), "output");
174    const char output_file_base_name[] = "output.txt";
175    ASSERT_EQ(0, MkDirAll(output_dir));
176    EXPECT_TRUE(RunTests(PlatformRunTest, {test_name},
177                         output_dir.c_str(), output_file_base_name, verbosity,
178                         &num_failed, &results));
179    EXPECT_EQ(0, num_failed);
180    EXPECT_EQ(1, results.size());
181    EXPECT_LE(1, results[0]->data_sinks.size());
182
183    END_TEST;
184}
185
186bool RunAllTestsPublishData() {
187    BEGIN_TEST;
188
189    ScopedTestDir test_dir;
190    fbl::String test_name = JoinPath(test_dir.path(), "publish-data-helper");
191    ScopedTestFile file(test_name.c_str(), "/boot/bin/publish-data-helper");
192
193    const fbl::String output_dir =
194        JoinPath(test_dir.path(), "run-all-tests-output-1");
195    EXPECT_EQ(0, MkDirAll(output_dir));
196
197    const char* const argv[] = {"./runtests", "-o", output_dir.c_str(),
198      test_dir.path()};
199    TestStopwatch stopwatch;
200    EXPECT_EQ(EXIT_SUCCESS, DiscoverAndRunTests(PlatformRunTest, 4, argv, {},
201                                                &stopwatch, ""));
202
203    // Prepare the expected output.
204    fbl::String test_output_rel_path;
205    ASSERT_TRUE(GetOutputFileRelPath(output_dir, test_name,
206                                     &test_output_rel_path));
207
208    fbl::StringBuffer<1024> expected_output_buf;
209    expected_output_buf.AppendPrintf(
210        "      \"name\": \"%s\",\n"
211        "      \"output_file\": \"%s\",\n"
212        "      \"result\": \"PASS\"",
213        test_name.c_str(),
214        test_output_rel_path.c_str() + 1); // +1 to discard the leading slash.
215
216    fbl::String test_data_sink_rel_path;
217    ASSERT_TRUE(GetOutputFileRelPath(output_dir, JoinPath(test_name, "test"),
218                                     &test_data_sink_rel_path));
219
220    fbl::StringBuffer<1024> expected_data_sink_buf;
221    expected_data_sink_buf.AppendPrintf(
222        "        \"test\": [\n"
223        "          {\n"
224        "            \"name\": \"test\",\n"
225        "            \"file\": \"%s\"\n"
226        "          }\n"
227        "        ]",
228        test_data_sink_rel_path.c_str() + 1); // +1 to discard the leading slash.
229
230    // Extract the actual output.
231    const fbl::String output_path = JoinPath(output_dir, "summary.json");
232    FILE* output_file = fopen(output_path.c_str(), "r");
233    ASSERT_TRUE(output_file);
234    char buf[1024];
235    memset(buf, 0, sizeof(buf));
236    EXPECT_LT(0, fread(buf, sizeof(buf[0]), sizeof(buf), output_file));
237    fclose(output_file);
238
239    EXPECT_NONNULL(strstr(buf, expected_output_buf.c_str()));
240    EXPECT_NONNULL(strstr(buf, expected_data_sink_buf.c_str()));
241
242    END_TEST;
243}
244
245BEGIN_TEST_CASE(FuchsiaComponentInfo)
246RUN_TEST_SMALL(TestFileComponentInfoTest)
247END_TEST_CASE(FuchsiaComponentInfo)
248
249BEGIN_TEST_CASE(PublishDataTests)
250RUN_TEST(RunTestDontPublishData)
251RUN_TEST_MEDIUM(RunTestsPublishData)
252RUN_TEST_MEDIUM(RunAllTestsPublishData)
253END_TEST_CASE(PublishDataTests)
254
255} // namespace
256} // namespace runtests
257