VirtualBox

source: vbox/trunk/src/VBox/Main/testcase/tstMediumLock.cpp

Last change on this file was 106061, checked in by vboxsync, 3 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.7 KB
Line 
1/* $Id: tstMediumLock.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * Medium lock test cases.
4 */
5
6/*
7 * Copyright (C) 2013-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#define LOG_ENABLED
29#define LOG_GROUP LOG_GROUP_MAIN
30#include <VBox/log.h>
31
32#include <VBox/com/com.h>
33#include <VBox/com/ptr.h>
34#include <VBox/com/defs.h>
35#include <VBox/com/array.h>
36#include <VBox/com/string.h>
37#include <VBox/com/VirtualBox.h>
38
39#include <iprt/assert.h>
40#include <iprt/uuid.h>
41#include <iprt/path.h>
42#include <iprt/string.h>
43#include <iprt/initterm.h>
44#include <iprt/test.h>
45
46using namespace com;
47
48
49#define TEST_RT_SUCCESS(x,y,z) \
50 do \
51 { \
52 int rc = (y); \
53 if (RT_FAILURE(rc)) \
54 RTTestFailed((x), "%s %Rrc", (z), rc); \
55 } while (0)
56
57#define TEST_COM_SUCCESS(x,y,z) \
58 do \
59 { \
60 HRESULT hrc = (y); \
61 if (FAILED(hrc)) \
62 RTTestFailed((x), "%s %Rhrc", (z), hrc); \
63 } while (0)
64
65#define TEST_COM_FAILURE(x,y,z) \
66 do \
67 { \
68 HRESULT hrc = (y); \
69 if (SUCCEEDED(hrc)) \
70 RTTestFailed((x), "%s", (z)); \
71 } while (0)
72
73int main(int argc, char *argv[])
74{
75 /* Init the runtime without loading the support driver. */
76 RTR3InitExe(argc, &argv, 0);
77
78 RTTEST hTest;
79 RTEXITCODE rcExit = RTTestInitAndCreate("tstMediumLock", &hTest);
80 if (rcExit)
81 return rcExit;
82 RTTestBanner(hTest);
83
84 bool fComInit = false;
85 ComPtr<IVirtualBoxClient> pVirtualBoxClient;
86 ComPtr<IVirtualBox> pVirtualBox;
87 char szPathTemp[RTPATH_MAX] = "";
88 ComPtr<IMedium> pMedium;
89
90 if (!RTTestSubErrorCount(hTest))
91 {
92 RTTestSub(hTest, "Constructing temp image name");
93 TEST_RT_SUCCESS(hTest, RTPathTemp(szPathTemp, sizeof(szPathTemp)), "temp directory");
94 RTUUID uuid;
95 RTUuidCreate(&uuid);
96 char szFile[50];
97 RTStrPrintf(szFile, sizeof(szFile), "%RTuuid.vdi", &uuid);
98 TEST_RT_SUCCESS(hTest, RTPathAppend(szPathTemp, sizeof(szPathTemp), szFile), "concatenate image name");
99 }
100
101 if (!RTTestSubErrorCount(hTest))
102 {
103 RTTestSub(hTest, "Initializing COM");
104 TEST_COM_SUCCESS(hTest, Initialize(), "init");
105 }
106
107 if (!RTTestSubErrorCount(hTest))
108 {
109 fComInit = true;
110
111 RTTestSub(hTest, "Getting VirtualBox reference");
112 TEST_COM_SUCCESS(hTest, pVirtualBoxClient.createInprocObject(CLSID_VirtualBoxClient), "vboxclient reference");
113 TEST_COM_SUCCESS(hTest, pVirtualBoxClient->COMGETTER(VirtualBox)(pVirtualBox.asOutParam()), "vbox reference");
114 }
115
116 if (!RTTestSubErrorCount(hTest))
117 {
118 RTTestSub(hTest, "Creating temp hard disk medium");
119 TEST_COM_SUCCESS(hTest, pVirtualBox->CreateMedium(Bstr("VDI").raw(), Bstr(szPathTemp).raw(), AccessMode_ReadWrite, DeviceType_HardDisk, pMedium.asOutParam()), "create medium");
120 if (!pMedium.isNull())
121 {
122 ComPtr<IProgress> pProgress;
123 SafeArray<MediumVariant_T> variant;
124 variant.push_back(MediumVariant_Standard);
125 TEST_COM_SUCCESS(hTest, pMedium->CreateBaseStorage(_1M, ComSafeArrayAsInParam(variant), pProgress.asOutParam()), "create base storage");
126 if (!pProgress.isNull())
127 TEST_COM_SUCCESS(hTest, pProgress->WaitForCompletion(30000), "waiting for completion of create");
128 }
129 }
130
131 if (!RTTestSubErrorCount(hTest))
132 {
133 RTTestSub(hTest, "Write locks");
134 ComPtr<IToken> pToken1, pToken2;
135
136 MediumState_T mediumState = MediumState_NotCreated;
137 TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting state");
138 if (mediumState != MediumState_Created)
139 RTTestFailed(hTest, "wrong medium state %d", mediumState);
140
141 TEST_COM_SUCCESS(hTest, pMedium->LockWrite(pToken1.asOutParam()), "write lock");
142
143 TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting lock write state");
144 if (mediumState != MediumState_LockedWrite)
145 RTTestFailed(hTest, "wrong lock write medium state %d", mediumState);
146
147 TEST_COM_FAILURE(hTest, pMedium->LockWrite(pToken2.asOutParam()), "nested write lock succeeded");
148 if (!pToken2.isNull())
149 RTTestFailed(hTest, "pToken2 is not null");
150
151 TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting after nested lock write state");
152 if (mediumState != MediumState_LockedWrite)
153 RTTestFailed(hTest, "wrong after nested lock write medium state %d", mediumState);
154
155 if (!pToken1.isNull())
156 TEST_COM_SUCCESS(hTest, pToken1->Abandon(), "write unlock");
157 else
158 RTTestFailed(hTest, "pToken1 is null");
159
160 TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting unlock write state");
161 if (mediumState != MediumState_Created)
162 RTTestFailed(hTest, "wrong unlock write medium state %d", mediumState);
163 }
164
165 if (!RTTestSubErrorCount(hTest))
166 {
167 RTTestSub(hTest, "Read locks");
168 ComPtr<IToken> pToken1, pToken2;
169
170 MediumState_T mediumState = MediumState_NotCreated;
171 TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting state");
172 if (mediumState != MediumState_Created)
173 RTTestFailed(hTest, "wrong medium state %d", mediumState);
174
175 TEST_COM_SUCCESS(hTest, pMedium->LockRead(pToken1.asOutParam()), "read lock");
176
177 TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting lock read state");
178 if (mediumState != MediumState_LockedRead)
179 RTTestFailed(hTest, "wrong lock read medium state %d", mediumState);
180
181 TEST_COM_SUCCESS(hTest, pMedium->LockRead(pToken2.asOutParam()), "nested read lock failed");
182
183 TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting after nested lock read state");
184 if (mediumState != MediumState_LockedRead)
185 RTTestFailed(hTest, "wrong after nested lock read medium state %d", mediumState);
186
187 if (!pToken2.isNull())
188 TEST_COM_SUCCESS(hTest, pToken2->Abandon(), "read nested unlock");
189 else
190 RTTestFailed(hTest, "pToken2 is null");
191
192 TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting after nested lock read state");
193 if (mediumState != MediumState_LockedRead)
194 RTTestFailed(hTest, "wrong after nested lock read medium state %d", mediumState);
195
196 if (!pToken1.isNull())
197 TEST_COM_SUCCESS(hTest, pToken1->Abandon(), "read nested unlock");
198 else
199 RTTestFailed(hTest, "pToken1 is null");
200
201 TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting unlock read state");
202 if (mediumState != MediumState_Created)
203 RTTestFailed(hTest, "wrong unlock read medium state %d", mediumState);
204 }
205
206 if (!RTTestSubErrorCount(hTest))
207 {
208 RTTestSub(hTest, "Mixing write and read locks");
209 ComPtr<IToken> pToken1, pToken2;
210
211 MediumState_T mediumState = MediumState_NotCreated;
212 TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting state");
213 if (mediumState != MediumState_Created)
214 RTTestFailed(hTest, "wrong medium state %d", mediumState);
215
216 TEST_COM_SUCCESS(hTest, pMedium->LockWrite(pToken1.asOutParam()), "write lock");
217
218 TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting lock write state");
219 if (mediumState != MediumState_LockedWrite)
220 RTTestFailed(hTest, "wrong lock write medium state %d", mediumState);
221
222 TEST_COM_FAILURE(hTest, pMedium->LockRead(pToken2.asOutParam()), "write+read lock succeeded");
223 if (!pToken2.isNull())
224 RTTestFailed(hTest, "pToken2 is not null");
225
226 TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting after nested lock write state");
227 if (mediumState != MediumState_LockedWrite)
228 RTTestFailed(hTest, "wrong after nested lock write medium state %d", mediumState);
229
230 if (!pToken1.isNull())
231 TEST_COM_SUCCESS(hTest, pToken1->Abandon(), "write unlock");
232 else
233 RTTestFailed(hTest, "pToken1 is null");
234
235 TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting unlock write state");
236 if (mediumState != MediumState_Created)
237 RTTestFailed(hTest, "wrong unlock write medium state %d", mediumState);
238 }
239
240 if (!RTTestSubErrorCount(hTest))
241 {
242 RTTestSub(hTest, "Mixing read and write locks");
243 ComPtr<IToken> pToken1, pToken2;
244
245 MediumState_T mediumState = MediumState_NotCreated;
246 TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting state");
247 if (mediumState != MediumState_Created)
248 RTTestFailed(hTest, "wrong medium state %d", mediumState);
249
250 TEST_COM_SUCCESS(hTest, pMedium->LockRead(pToken1.asOutParam()), "read lock");
251
252 TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting lock read state");
253 if (mediumState != MediumState_LockedRead)
254 RTTestFailed(hTest, "wrong lock read medium state %d", mediumState);
255
256 TEST_COM_FAILURE(hTest, pMedium->LockWrite(pToken2.asOutParam()), "read+write lock succeeded");
257 if (!pToken2.isNull())
258 RTTestFailed(hTest, "pToken2 is not null");
259
260 TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting after nested lock read state");
261 if (mediumState != MediumState_LockedRead)
262 RTTestFailed(hTest, "wrong after nested lock read medium state %d", mediumState);
263
264 if (!pToken1.isNull())
265 TEST_COM_SUCCESS(hTest, pToken1->Abandon(), "read unlock");
266 else
267 RTTestFailed(hTest, "pToken1 is null");
268
269 TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting unlock read state");
270 if (mediumState != MediumState_Created)
271 RTTestFailed(hTest, "wrong unlock read medium state %d", mediumState);
272 }
273
274 /* Cleanup, also part of the testcase */
275
276 if (!pMedium.isNull())
277 {
278 RTTestSub(hTest, "Closing medium");
279 MediumState_T mediumState = MediumState_NotCreated;
280 TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting state");
281 if (mediumState == MediumState_Created)
282 {
283 ComPtr<IProgress> pProgress;
284 TEST_COM_SUCCESS(hTest, pMedium->DeleteStorage(pProgress.asOutParam()), "deleting storage");
285 if (!pProgress.isNull())
286 TEST_COM_SUCCESS(hTest, pProgress->WaitForCompletion(30000), "waiting for completion of delete");
287 }
288 TEST_COM_SUCCESS(hTest, pMedium->Close(), "closing");
289 pMedium.setNull();
290 }
291
292 pVirtualBox.setNull();
293 pVirtualBoxClient.setNull();
294
295 /* Make sure that there are no object references alive here, XPCOM does
296 * a very bad job at cleaning up such leftovers, spitting out warning
297 * messages in a debug build. */
298
299 if (fComInit)
300 {
301 RTTestIPrintf(RTTESTLVL_DEBUG, "Shutting down COM...\n");
302 Shutdown();
303 }
304
305 /*
306 * Summary.
307 */
308 return RTTestSummaryAndDestroy(hTest);
309}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette