environment.cpp 5.99 KB
Newer Older
1
/*******************************************************************************
Thomas Voß's avatar
Thomas Voß committed
2
3
4
 *
 * X testing environment - Google Test environment feat. dummy x server
 *
5
 * Copyright (C) 2011, 2012 Canonical Ltd.
Thomas Voß's avatar
Thomas Voß committed
6
 *
7
8
9
10
11
12
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
Thomas Voß's avatar
Thomas Voß committed
13
 *
14
15
16
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
Thomas Voß's avatar
Thomas Voß committed
17
 *
18
19
20
21
22
23
24
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
Thomas Voß's avatar
Thomas Voß committed
25
 *
26
 ******************************************************************************/
Thomas Voß's avatar
Thomas Voß committed
27

28
29
#include "xorg/gtest/xorg-gtest-environment.h"
#include "xorg/gtest/xorg-gtest-process.h"
30
#include "xorg/gtest/xorg-gtest-xserver.h"
31
#include "defines.h"
Thomas Voß's avatar
Thomas Voß committed
32
33
34
35

#include <sys/types.h>
#include <unistd.h>

36
37
38
#include <cerrno>
#include <csignal>
#include <cstdlib>
Thomas Voß's avatar
Thomas Voß committed
39
#include <cstring>
40
#include <fstream>
Thomas Voß's avatar
Thomas Voß committed
41
#include <iostream>
42
#include <stdexcept>
Thomas Voß's avatar
Thomas Voß committed
43
44
45

#include <X11/Xlib.h>

46
struct xorg::testing::Environment::Private {
47
48
49
  Private()
      : path_to_conf(DUMMY_CONF_PATH), path_to_log_file(DEFAULT_XORG_LOGFILE),
        path_to_server(DEFAULT_XORG_SERVER), display(DEFAULT_DISPLAY) {
50
51
  }

52
  std::string path_to_conf;
53
  std::string path_to_log_file;
54
55
  std::string path_to_server;
  int display;
56
  XServer server;
57
58
};

59
60
xorg::testing::Environment::Environment()
    : d_(new Private) {
Thomas Voß's avatar
Thomas Voß committed
61
62
}

63
xorg::testing::Environment::~Environment() {}
64

65
void xorg::testing::Environment::set_log_file(const std::string& path_to_log_file)
66
67
68
69
70
{
  SetLogFile(path_to_log_file);
}

void xorg::testing::Environment::SetLogFile(const std::string& path_to_log_file)
71
72
73
74
{
  d_->path_to_log_file = path_to_log_file;
}

75
const std::string& xorg::testing::Environment::GetLogFile() const
76
77
78
79
{
  return d_->path_to_log_file;
}

80
void xorg::testing::Environment::SetConfigFile(const std::string& path_to_conf_file)
81
{
82
  d_->path_to_conf = path_to_conf_file;
83
84
}

85
const std::string& xorg::testing::Environment::GetConfigFile() const
86
87
88
89
{
  return d_->path_to_conf;
}

90
void xorg::testing::Environment::SetServerPath(const std::string& path_to_server)
91
92
93
94
{
  d_->path_to_server = path_to_server;
}

95
const std::string& xorg::testing::Environment::GetServerPath() const
96
97
98
99
{
  return d_->path_to_server;
}

100
void xorg::testing::Environment::SetDisplayNumber(int display_num)
101
102
103
104
{
  d_->display = display_num;
}

105
void xorg::testing::Environment::SetUp() {
Thomas Voß's avatar
Thomas Voß committed
106
  static char display_string[6];
107
  snprintf(display_string, 6, ":%d", d_->display);
108

109
110
111
112
113
114
115
116
117
118
  Display* test_display = XOpenDisplay(display_string);
  if (test_display) {
    XCloseDisplay(test_display);
    std::string message;
    message += "A server is already running on ";
    message += display_string;
    message += ".";
    throw std::runtime_error(message);
  }

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
  /* The Xorg server won't start unless the log file and the old log file are
   * writable. */
  std::ofstream log_test;
  log_test.open(d_->path_to_log_file.c_str(), std::ofstream::out);
  log_test.close();
  if (log_test.fail()) {
    std::string message;
    message += "X.org server log file ";
    message += d_->path_to_log_file;
    message += " is not writable.";
    throw std::runtime_error(message);
  }

  std::string old_log_file = d_->path_to_log_file.c_str();
  old_log_file += ".old";
  log_test.open(old_log_file.c_str(), std::ofstream::out);
  log_test.close();
  if (log_test.fail()) {
    std::string message;
    message += "X.org old server log file ";
    message += old_log_file;
    message += " is not writable.";
    throw std::runtime_error(message);
  }

144
  d_->server.SetDisplayNumber(d_->display);
145
146
  d_->server.SetOption("-logfile", d_->path_to_log_file);
  d_->server.SetOption("-config", d_->path_to_conf);
147
  d_->server.Start(d_->path_to_server);
148
  d_->server.WaitForConnections();
149

150
  Process::SetEnv("DISPLAY", display_string, true);
Thomas Voß's avatar
Thomas Voß committed
151
152
}

153
void xorg::testing::Environment::TearDown() {
154
  if (d_->server.Terminate()) {
155
156
    for (int i = 0; i < 10; i++) {
      int status;
157
      int pid = waitpid(d_->server.Pid(), &status, WNOHANG);
158

159
      if (pid == d_->server.Pid())
160
161
162
163
        return;

      sleep(1); /* Give the dummy X server more time to shut down */
    }
164
  }
165
166

  Kill();
Thomas Voß's avatar
Thomas Voß committed
167
}
168
169

void xorg::testing::Environment::Kill() {
170
  if (!d_->server.Kill())
171
172
    std::cerr << "Warning: Failed to kill dummy Xorg server: "
              << std::strerror(errno) << "\n";
173
174
175

  for (int i = 0; i < 10; i++) {
    int status;
176
    int pid = waitpid(d_->server.Pid(), &status, WNOHANG);
177

178
    if (pid == d_->server.Pid())
179
180
181
182
183
184
      return;

      sleep(1); /* Give the dummy X server more time to shut down */
  }

  std::cerr << "Warning: Dummy X server did not shut down\n";
185
}
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222


/* DEPRECATED */
const std::string& xorg::testing::Environment::log_file() const
{
  return GetLogFile();
}

void xorg::testing::Environment::set_conf_file(const std::string& path_conf_file)
{
  return SetConfigFile(path_conf_file);
}

const std::string& xorg::testing::Environment::conf_file() const
{
  return GetConfigFile();
}

void xorg::testing::Environment::set_server(const std::string& path_to_server)
{
  SetServerPath(path_to_server);
}

const std::string& xorg::testing::Environment::server() const
{
  return GetServerPath();
}

void xorg::testing::Environment::set_display(int display_num)
{
  SetDisplayNumber(display_num);
}

int xorg::testing::Environment::display() const
{
  return d_->display;
}