blob: 430f39b60408d41fcd117f197c18b50870b64d22 [file] [log] [blame]
adlr@google.com3defe6a2009-12-04 20:57:17 +00001// Copyright (c) 2009 The Chromium 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 <sys/stat.h>
6#include <sys/types.h>
7#include <unistd.h>
8#include <string>
9#include <vector>
10#include "base/string_util.h"
11#include <glib.h>
12#include <gtest/gtest.h>
13#include "update_engine/subprocess.h"
14#include "update_engine/test_utils.h"
15#include "update_engine/utils.h"
16
17using std::string;
18using std::vector;
19
20namespace chromeos_update_engine {
21
22class SubprocessTest : public ::testing::Test {
23 protected:
24 bool callback_done;
25};
26
27namespace {
28const int kLocalHttpPort = 8080;
29
30void Callback(int return_code, void *p) {
31 EXPECT_EQ(256, return_code);
32 GMainLoop* loop = reinterpret_cast<GMainLoop*>(p);
33 g_main_loop_quit(loop);
34}
35
36gboolean LaunchFalseInMainLoop(gpointer data) {
37 vector<string> cmd;
38 cmd.push_back("/bin/false");
39 Subprocess::Get().Exec(cmd, Callback, data);
40 return FALSE;
41}
42} // namespace {}
43
44TEST(SubprocessTest, SimpleTest) {
45 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
46 g_timeout_add(0, &LaunchFalseInMainLoop, loop);
47 g_main_loop_run(loop);
48 g_main_loop_unref(loop);
49}
50
51namespace {
52void CallbackBad(int return_code, void *p) {
53 CHECK(false) << "should never be called.";
54}
55
56struct CancelTestData {
57 bool spawned;
58 GMainLoop *loop;
59};
60
61gboolean StartAndCancelInRunLoop(gpointer data) {
62 CancelTestData* cancel_test_data = reinterpret_cast<CancelTestData*>(data);
63 vector<string> cmd;
64 cmd.push_back("./test_http_server");
65 uint32 tag = Subprocess::Get().Exec(cmd, CallbackBad, NULL);
66 EXPECT_NE(0, tag);
67 cancel_test_data->spawned = true;
68 printf("spawned\n");
69 // Wait for server to be up and running
70 for (;;) {
71 int status =
72 System(StringPrintf("wget -O /dev/null http://127.0.0.1:%d/foo",
73 kLocalHttpPort));
74 EXPECT_NE(-1, status) << "system() failed";
75 EXPECT_TRUE(WIFEXITED(status))
76 << "command failed to run or died abnormally";
77 if (0 == WEXITSTATUS(status))
78 break;
79 usleep(100 * 1000); // 100 ms
80 }
81 Subprocess::Get().CancelExec(tag);
82 return FALSE;
83}
84} // namespace {}
85
86gboolean ExitWhenDone(gpointer data) {
87 CancelTestData* cancel_test_data = reinterpret_cast<CancelTestData*>(data);
88 if (cancel_test_data->spawned && !Subprocess::Get().SubprocessInFlight()) {
89 // tear down the sub process
90 printf("tear down time\n");
91 int status =
92 System(StringPrintf("wget http://127.0.0.1:%d/quitquitquit",
93 kLocalHttpPort));
94 EXPECT_NE(-1, status) << "system() failed";
95 EXPECT_TRUE(WIFEXITED(status))
96 << "command failed to run or died abnormally";
97 g_main_loop_quit(cancel_test_data->loop);
98 return FALSE;
99 }
100 return TRUE;
101}
102
103TEST(SubprocessTest, CancelTest) {
104 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
105 CancelTestData cancel_test_data;
106 cancel_test_data.spawned = false;
107 cancel_test_data.loop = loop;
108 g_timeout_add(100, &StartAndCancelInRunLoop, &cancel_test_data);
109 g_timeout_add(10, &ExitWhenDone, &cancel_test_data);
110 g_main_loop_run(loop);
111 g_main_loop_unref(loop);
112 printf("here\n");
113}
114
115} // namespace chromeos_update_engine