[cosmetic] cleanup copyright headers
[vuplus_xbmc] / xbmc / windowing / tests / wayland / WestonTest.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20 #include <sstream>
21 #include <stdexcept>
22
23 #include <boost/array.hpp>
24
25 #include <signal.h>
26
27 #include "test/TestUtils.h"
28 #include "utils/log.h"
29
30 #include "TmpEnv.h"
31 #include "WestonProcess.h"
32 #include "WestonTest.h"
33
34 namespace xt = xbmc::test;
35
36 namespace
37 {
38 class TempFileWrapper :
39   boost::noncopyable
40 {
41 public:
42
43   TempFileWrapper(const CStdString &suffix);
44   ~TempFileWrapper();
45   
46   void FetchDirectory(CStdString &directory);
47   void FetchFilename(CStdString &name);
48 private:
49
50   XFILE::CFile *m_file;
51 };
52
53 TempFileWrapper::TempFileWrapper(const CStdString &suffix) :
54   m_file(CXBMCTestUtils::Instance().CreateTempFile(suffix))
55 {
56 }
57
58 TempFileWrapper::~TempFileWrapper()
59 {
60   CXBMCTestUtils::Instance().DeleteTempFile(m_file);
61 }
62
63 void TempFileWrapper::FetchDirectory(CStdString &directory)
64 {
65   directory = CXBMCTestUtils::Instance().TempFileDirectory(m_file);
66   /* Strip trailing "/" */
67   directory.resize(directory.size() - 1);
68 }
69
70 void TempFileWrapper::FetchFilename(CStdString &name)
71 {
72   CStdString path(CXBMCTestUtils::Instance().TempFilePath(m_file));
73   CStdString directory(CXBMCTestUtils::Instance().TempFileDirectory(m_file));
74   
75   name = path.substr(directory.size());
76 }
77
78 class SavedTempSocket :
79   boost::noncopyable
80 {
81 public:
82
83   SavedTempSocket();
84
85   const CStdString & FetchFilename();
86   const CStdString & FetchDirectory();
87
88 private:
89
90   CStdString m_filename;
91   CStdString m_directory;
92 };
93
94 SavedTempSocket::SavedTempSocket()
95 {
96   TempFileWrapper wrapper("");
97   wrapper.FetchDirectory(m_directory);
98   wrapper.FetchFilename(m_filename);
99 }
100
101 const CStdString &
102 SavedTempSocket::FetchFilename()
103 {
104   return m_filename;
105 }
106
107 const CStdString &
108 SavedTempSocket::FetchDirectory()
109 {
110   return m_directory;
111 }
112
113 template <typename Iterator>
114 class SignalGuard :
115   boost::noncopyable
116 {
117 public:
118
119   SignalGuard(const Iterator &begin,
120               const Iterator &end);
121   ~SignalGuard();
122 private:
123
124   sigset_t mask;
125 };
126
127 template <typename Iterator>
128 SignalGuard<Iterator>::SignalGuard(const Iterator &begin,
129                                    const Iterator &end)
130 {
131   sigemptyset(&mask);
132   for (Iterator it = begin;
133        it != end;
134        ++it)
135     sigaddset(&mask, *it);
136
137   if (sigprocmask(SIG_BLOCK, &mask, NULL))
138   {
139     std::stringstream ss;
140     ss << "sigprogmask: "
141        << strerror(errno);
142     throw std::runtime_error(ss.str());
143   }
144 }
145
146 template <typename Iterator>
147 SignalGuard<Iterator>::~SignalGuard()
148 {
149   if (sigprocmask(SIG_UNBLOCK, &mask, NULL))
150     CLog::Log(LOGERROR, "Failed to unblock signals");
151 }
152
153 typedef boost::array<int, 4> SigArray;
154 SigArray BlockedSignals =
155 {
156   {
157     SIGUSR2,
158     SIGCHLD
159   }
160 };
161 }
162
163 class WestonTest::Private
164 {
165 public:
166   
167   Private();
168   ~Private();
169   
170   CStdString m_xbmcTestBase;
171   SavedTempSocket m_tempSocketName;
172   TmpEnv m_xdgRuntimeDir;
173
174   SignalGuard<SigArray::iterator> m_signalGuard;
175
176   xt::Process m_process;
177 };
178
179 WestonTest::WestonTest() :
180   priv(new Private())
181 {
182 }
183
184 /* We need a defined destructor, otherwise we will
185  * generate the destructors for all of the owned objects
186  * multiple times where the definitions for those
187  * destructors is unavailable */
188 WestonTest::~WestonTest()
189 {
190 }
191
192 WestonTest::Private::Private() :
193   m_xbmcTestBase(CXBMCTestUtils::Instance().ReferenceFilePath("")),
194   /* We want wayland (client and server) to look in our
195    * temp file directory for the socket */
196   m_xdgRuntimeDir("XDG_RUNTIME_DIR", m_tempSocketName.FetchDirectory().c_str()),
197   /* Block emission of SIGUSR2 so that we can wait on it */
198   m_signalGuard(BlockedSignals.begin(), BlockedSignals.end()),
199   m_process(m_xbmcTestBase,
200             m_tempSocketName.FetchFilename())
201 {
202 }
203
204 WestonTest::Private::~Private()
205 {
206 }
207
208 pid_t
209 WestonTest::Pid()
210 {
211   return priv->m_process.Pid();
212 }
213
214 const CStdString &
215 WestonTest::TempSocketName()
216 {
217   return priv->m_tempSocketName.FetchFilename();
218 }
219
220 void
221 WestonTest::SetUp()
222 {
223   priv->m_process.WaitForSignal(SIGUSR2, xt::Process::DefaultProcessWaitTimeout);
224 }