Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / cloud_print / virtual_driver / win / port_monitor / port_monitor_unittest.cc
1 // Copyright (c) 2012 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 "cloud_print/virtual_driver/win/port_monitor/port_monitor.h"
6
7 #include <winspool.h>
8
9 #include "base/files/file_util.h"
10 #include "base/path_service.h"
11 #include "base/strings/string16.h"
12 #include "base/win/registry.h"
13 #include "base/win/scoped_handle.h"
14 #include "cloud_print/virtual_driver/win/port_monitor/spooler_win.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace cloud_print {
18
19 const wchar_t kChromeExePath[] = L"google\\chrome\\application\\chrometest.exe";
20 const wchar_t kChromeExePathRegValue[] = L"PathToChromeTestExe";
21 const wchar_t kChromeProfilePathRegValue[] = L"PathToChromeTestProfile";
22 const bool kIsUnittest = true;
23
24 namespace {
25
26 const wchar_t kAlternateChromeExePath[] =
27     L"google\\chrome\\application\\chrometestalternate.exe";
28
29 const wchar_t kCloudPrintRegKey[] = L"Software\\Google\\CloudPrint";
30
31 }  // namespace
32
33 class PortMonitorTest : public testing::Test  {
34  public:
35   PortMonitorTest() {}
36  protected:
37   // Creates a registry entry pointing at a chrome
38   virtual void SetUpChromeExeRegistry() {
39     // Create a temporary chrome.exe location value.
40     base::win::RegKey key(HKEY_CURRENT_USER,
41                           cloud_print::kCloudPrintRegKey,
42                           KEY_ALL_ACCESS);
43
44     base::FilePath path;
45     PathService::Get(base::DIR_LOCAL_APP_DATA, &path);
46     path = path.Append(kAlternateChromeExePath);
47     ASSERT_EQ(ERROR_SUCCESS,
48               key.WriteValue(cloud_print::kChromeExePathRegValue,
49                              path.value().c_str()));
50     base::FilePath temp;
51     PathService::Get(base::DIR_TEMP, &temp);
52     // Write any dir here.
53     ASSERT_EQ(ERROR_SUCCESS,
54               key.WriteValue(cloud_print::kChromeProfilePathRegValue,
55                              temp.value().c_str()));
56   }
57   // Deletes the registry entry created in SetUpChromeExeRegistry
58   virtual void DeleteChromeExeRegistry() {
59     base::win::RegKey key(HKEY_CURRENT_USER,
60                           cloud_print::kCloudPrintRegKey,
61                           KEY_ALL_ACCESS);
62     key.DeleteValue(cloud_print::kChromeExePathRegValue);
63     key.DeleteValue(cloud_print::kChromeProfilePathRegValue);
64   }
65
66   virtual void CreateTempChromeExeFiles() {
67     base::FilePath path;
68     PathService::Get(base::DIR_LOCAL_APP_DATA, &path);
69     base::FilePath main_path = path.Append(kChromeExePath);
70     ASSERT_TRUE(base::CreateDirectory(main_path));
71     base::FilePath alternate_path = path.Append(kAlternateChromeExePath);
72     ASSERT_TRUE(base::CreateDirectory(alternate_path));
73   }
74
75   virtual void DeleteTempChromeExeFiles() {
76     base::FilePath path;
77     PathService::Get(base::DIR_LOCAL_APP_DATA, &path);
78     base::FilePath main_path = path.Append(kChromeExePath);
79     ASSERT_TRUE(base::DeleteFile(main_path, true));
80     PathService::Get(base::DIR_LOCAL_APP_DATA, &path);
81     base::FilePath alternate_path = path.Append(kAlternateChromeExePath);
82     ASSERT_TRUE(base::DeleteFile(alternate_path, true));
83   }
84
85  protected:
86   virtual void SetUp() {
87     SetUpChromeExeRegistry();
88   }
89
90   virtual void TearDown() {
91     DeleteChromeExeRegistry();
92   }
93
94  private:
95   DISALLOW_COPY_AND_ASSIGN(PortMonitorTest);
96 };
97
98 TEST_F(PortMonitorTest, GetChromeExePathTest) {
99   CreateTempChromeExeFiles();
100   base::FilePath chrome_path = cloud_print::GetChromeExePath();
101   EXPECT_FALSE(chrome_path.empty());
102   EXPECT_TRUE(
103       chrome_path.value().rfind(kAlternateChromeExePath) != std::string::npos);
104   EXPECT_TRUE(base::PathExists(chrome_path));
105   DeleteChromeExeRegistry();
106   chrome_path = cloud_print::GetChromeExePath();
107   // No Chrome or regular chrome path.
108   EXPECT_TRUE(chrome_path.empty() ||
109               chrome_path.value().rfind(kChromeExePath) == std::string::npos);
110 }
111
112 TEST_F(PortMonitorTest, GetChromeProfilePathTest) {
113   base::FilePath data_path = cloud_print::GetChromeProfilePath();
114   EXPECT_FALSE(data_path.empty());
115   base::FilePath temp;
116   PathService::Get(base::DIR_TEMP, &temp);
117   EXPECT_EQ(data_path, temp);
118   EXPECT_TRUE(base::DirectoryExists(data_path));
119   DeleteChromeExeRegistry();
120   data_path = cloud_print::GetChromeProfilePath();
121   EXPECT_TRUE(data_path.empty());
122 }
123
124 TEST_F(PortMonitorTest, EnumPortsTest) {
125   DWORD needed_bytes = 0;
126   DWORD returned = 0;
127   EXPECT_FALSE(Monitor2EnumPorts(NULL,
128                                  NULL,
129                                  1,
130                                  NULL,
131                                  0,
132                                  &needed_bytes,
133                                  &returned));
134   EXPECT_EQ(ERROR_INSUFFICIENT_BUFFER, GetLastError());
135   EXPECT_NE(0u, needed_bytes);
136   EXPECT_EQ(0u, returned);
137
138   BYTE* buffer = new BYTE[needed_bytes];
139   ASSERT_TRUE(buffer != NULL);
140   EXPECT_TRUE(Monitor2EnumPorts(NULL,
141                                 NULL,
142                                 1,
143                                 buffer,
144                                 needed_bytes,
145                                 &needed_bytes,
146                                 &returned));
147   EXPECT_NE(0u, needed_bytes);
148   EXPECT_EQ(1u, returned);
149   PORT_INFO_1* port_info_1 = reinterpret_cast<PORT_INFO_1*>(buffer);
150   EXPECT_TRUE(port_info_1->pName != NULL);
151   delete[] buffer;
152
153   returned = 0;
154   needed_bytes = 0;
155   EXPECT_FALSE(Monitor2EnumPorts(NULL,
156                                  NULL,
157                                  2,
158                                  NULL,
159                                  0,
160                                  &needed_bytes,
161                                  &returned));
162   EXPECT_EQ(ERROR_INSUFFICIENT_BUFFER, GetLastError());
163   EXPECT_NE(0u, needed_bytes);
164   EXPECT_EQ(0u, returned);
165
166   buffer = new BYTE[needed_bytes];
167   ASSERT_TRUE(buffer != NULL);
168   EXPECT_TRUE(Monitor2EnumPorts(NULL,
169                                 NULL,
170                                 2,
171                                 buffer,
172                                 needed_bytes,
173                                 &needed_bytes,
174                                 &returned));
175   EXPECT_NE(0u, needed_bytes);
176   EXPECT_EQ(1u, returned);
177   PORT_INFO_2* port_info_2 = reinterpret_cast<PORT_INFO_2*>(buffer);
178   EXPECT_TRUE(port_info_2->pPortName != NULL);
179   delete[] buffer;
180 }
181
182 TEST_F(PortMonitorTest, FlowTest) {
183   const wchar_t kXcvDataItem[] = L"MonitorUI";
184   MONITORINIT monitor_init = {0};
185   HANDLE monitor_handle = NULL;
186   HANDLE port_handle = NULL;
187   HANDLE xcv_handle = NULL;
188   DWORD bytes_processed = 0;
189   DWORD bytes_needed = 0;
190   const size_t kBufferSize = 100;
191   BYTE buffer[kBufferSize] = {0};
192
193   // Initialize the print monitor
194   MONITOR2* monitor2 = InitializePrintMonitor2(&monitor_init, &monitor_handle);
195   EXPECT_TRUE(monitor2 != NULL);
196   EXPECT_TRUE(monitor_handle != NULL);
197
198   // Test the XCV functions.  Used for reporting the location of the
199   // UI portion of the port monitor.
200   EXPECT_TRUE(monitor2->pfnXcvOpenPort != NULL);
201   EXPECT_TRUE(monitor2->pfnXcvOpenPort(monitor_handle, NULL, 0, &xcv_handle));
202   EXPECT_TRUE(xcv_handle != NULL);
203   EXPECT_TRUE(monitor2->pfnXcvDataPort != NULL);
204   EXPECT_EQ(ERROR_ACCESS_DENIED,
205             monitor2->pfnXcvDataPort(xcv_handle,
206                                      kXcvDataItem,
207                                      NULL,
208                                      0,
209                                      buffer,
210                                      kBufferSize,
211                                      &bytes_needed));
212   EXPECT_TRUE(monitor2->pfnXcvClosePort != NULL);
213   EXPECT_TRUE(monitor2->pfnXcvClosePort(xcv_handle));
214   EXPECT_TRUE(monitor2->pfnXcvOpenPort(monitor_handle,
215                                        NULL,
216                                        SERVER_ACCESS_ADMINISTER,
217                                        &xcv_handle));
218   EXPECT_TRUE(xcv_handle != NULL);
219   EXPECT_TRUE(monitor2->pfnXcvDataPort != NULL);
220   EXPECT_EQ(ERROR_SUCCESS,
221             monitor2->pfnXcvDataPort(xcv_handle,
222                                      kXcvDataItem,
223                                      NULL,
224                                      0,
225                                      buffer,
226                                      kBufferSize,
227                                      &bytes_needed));
228   EXPECT_TRUE(monitor2->pfnXcvClosePort != NULL);
229   EXPECT_TRUE(monitor2->pfnXcvClosePort(xcv_handle));
230
231   // Test opening the port and running a print job.
232   EXPECT_TRUE(monitor2->pfnOpenPort != NULL);
233   EXPECT_TRUE(monitor2->pfnOpenPort(monitor_handle, NULL, &port_handle));
234   EXPECT_TRUE(port_handle != NULL);
235   EXPECT_TRUE(monitor2->pfnStartDocPort != NULL);
236   EXPECT_TRUE(monitor2->pfnWritePort != NULL);
237   EXPECT_TRUE(monitor2->pfnReadPort != NULL);
238   EXPECT_TRUE(monitor2->pfnEndDocPort != NULL);
239
240   // These functions should fail if we have not impersonated the user.
241   EXPECT_FALSE(monitor2->pfnStartDocPort(
242       port_handle, const_cast<wchar_t*>(L""), 0, 0, NULL));
243   EXPECT_FALSE(monitor2->pfnWritePort(port_handle,
244                                      buffer,
245                                      kBufferSize,
246                                      &bytes_processed));
247   EXPECT_EQ(0, bytes_processed);
248   EXPECT_FALSE(monitor2->pfnReadPort(port_handle,
249                                      buffer,
250                                      sizeof(buffer),
251                                      &bytes_processed));
252   EXPECT_EQ(0u, bytes_processed);
253   EXPECT_FALSE(monitor2->pfnEndDocPort(port_handle));
254
255   // Now impersonate so we can test the success case.
256   ASSERT_TRUE(ImpersonateSelf(SecurityImpersonation));
257   EXPECT_TRUE(monitor2->pfnStartDocPort(
258       port_handle, const_cast<wchar_t*>(L""), 0, 0, NULL));
259   EXPECT_TRUE(monitor2->pfnWritePort(port_handle,
260                                      buffer,
261                                      kBufferSize,
262                                      &bytes_processed));
263   EXPECT_EQ(kBufferSize, bytes_processed);
264   EXPECT_FALSE(monitor2->pfnReadPort(port_handle,
265                                      buffer,
266                                      sizeof(buffer),
267                                      &bytes_processed));
268   EXPECT_EQ(0u, bytes_processed);
269   EXPECT_TRUE(monitor2->pfnEndDocPort(port_handle));
270   RevertToSelf();
271   EXPECT_TRUE(monitor2->pfnClosePort != NULL);
272   EXPECT_TRUE(monitor2->pfnClosePort(port_handle));
273   // Shutdown the port monitor.
274   Monitor2Shutdown(monitor_handle);
275 }
276
277 }  // namespace cloud_print
278