VirtualBox

source: vbox/trunk/src/VBox/Storage/testcase/tstVD-2.cpp

Last change on this file was 106061, checked in by vboxsync, 2 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: 7.8 KB
Line 
1/** @file
2 *
3 * Simple VBox HDD container test utility. Only fast tests.
4 */
5
6/*
7 * Copyright (C) 2006-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#include <VBox/err.h>
29#include <VBox/vd.h>
30#include <iprt/string.h>
31#include <iprt/stream.h>
32#include <iprt/file.h>
33#include <iprt/mem.h>
34#include <iprt/initterm.h>
35#include <iprt/rand.h>
36#include "stdio.h"
37#include "stdlib.h"
38
39
40/*********************************************************************************************************************************
41* Global Variables *
42*********************************************************************************************************************************/
43/** The error count. */
44unsigned g_cErrors = 0;
45
46static struct KeyValuePair {
47 const char *key;
48 const char *value;
49} aCfgNode[] = {
50 { "TargetName", "test" },
51 { "LUN", "1" },
52 { "TargetAddress", "address" },
53 { NULL, NULL }
54};
55
56static DECLCALLBACK(bool) tstAreKeysValid(void *pvUser, const char *pszzValid)
57{
58 RT_NOREF2(pvUser, pszzValid);
59 return true;
60}
61
62static const char *tstGetValueByKey(const char *pszKey)
63{
64 for (int i = 0; aCfgNode[i].key; i++)
65 if (!strcmp(aCfgNode[i].key, pszKey))
66 return aCfgNode[i].value;
67 return NULL;
68}
69
70static DECLCALLBACK(int) tstQuerySize(void *pvUser, const char *pszName, size_t *pcbValue)
71{
72 RT_NOREF1(pvUser);
73 const char *pszValue = tstGetValueByKey(pszName);
74 if (!pszValue)
75 return VERR_CFGM_VALUE_NOT_FOUND;
76 *pcbValue = strlen(pszValue) + 1;
77 return VINF_SUCCESS;
78}
79
80static DECLCALLBACK(int) tstQuery(void *pvUser, const char *pszName, char *pszValue, size_t cchValue)
81{
82 RT_NOREF1(pvUser);
83 const char *pszTmp = tstGetValueByKey(pszName);
84 if (!pszValue)
85 return VERR_CFGM_VALUE_NOT_FOUND;
86 size_t cchTmp = strlen(pszTmp) + 1;
87 if (cchValue < cchTmp)
88 return VERR_CFGM_NOT_ENOUGH_SPACE;
89 memcpy(pszValue, pszTmp, cchTmp);
90 return VINF_SUCCESS;
91}
92
93static const char *tstVDDeviceType(VDTYPE enmType)
94{
95 switch (enmType)
96 {
97 case VDTYPE_HDD:
98 return "HardDisk";
99 case VDTYPE_OPTICAL_DISC:
100 return "OpticalDisc";
101 case VDTYPE_FLOPPY:
102 return "Floppy";
103 default:
104 return "Unknown";
105 }
106}
107
108static int tstVDBackendInfo(void)
109{
110 int rc;
111#define MAX_BACKENDS 100
112 VDBACKENDINFO aVDInfo[MAX_BACKENDS];
113 unsigned cEntries;
114
115#define CHECK(str) \
116 do \
117 { \
118 RTPrintf("%s rc=%Rrc\n", str, rc); \
119 if (RT_FAILURE(rc)) \
120 return rc; \
121 } while (0)
122
123 rc = VDBackendInfo(MAX_BACKENDS, aVDInfo, &cEntries);
124 CHECK("VDBackendInfo()");
125
126 for (unsigned i=0; i < cEntries; i++)
127 {
128 RTPrintf("Backend %u: name=%s capabilities=%#06x extensions=",
129 i, aVDInfo[i].pszBackend, aVDInfo[i].uBackendCaps);
130 if (aVDInfo[i].paFileExtensions)
131 {
132 PCVDFILEEXTENSION pa = aVDInfo[i].paFileExtensions;
133 while (pa->pszExtension != NULL)
134 {
135 if (pa != aVDInfo[i].paFileExtensions)
136 RTPrintf(",");
137 RTPrintf("%s (%s)", pa->pszExtension, tstVDDeviceType(pa->enmType));
138 pa++;
139 }
140 if (pa == aVDInfo[i].paFileExtensions)
141 RTPrintf("<EMPTY>");
142 }
143 else
144 RTPrintf("<NONE>");
145 RTPrintf(" config=");
146 if (aVDInfo[i].paConfigInfo)
147 {
148 PCVDCONFIGINFO pa = aVDInfo[i].paConfigInfo;
149 while (pa->pszKey != NULL)
150 {
151 if (pa != aVDInfo[i].paConfigInfo)
152 RTPrintf(",");
153 RTPrintf("(key=%s type=", pa->pszKey);
154 switch (pa->enmValueType)
155 {
156 case VDCFGVALUETYPE_INTEGER:
157 RTPrintf("integer");
158 break;
159 case VDCFGVALUETYPE_STRING:
160 RTPrintf("string");
161 break;
162 case VDCFGVALUETYPE_BYTES:
163 RTPrintf("bytes");
164 break;
165 default:
166 RTPrintf("INVALID!");
167 }
168 RTPrintf(" default=");
169 if (pa->pszDefaultValue)
170 RTPrintf("%s", pa->pszDefaultValue);
171 else
172 RTPrintf("<NONE>");
173 RTPrintf(" flags=");
174 if (!pa->uKeyFlags)
175 RTPrintf("none");
176 unsigned cFlags = 0;
177 if (pa->uKeyFlags & VD_CFGKEY_MANDATORY)
178 {
179 if (cFlags)
180 RTPrintf(",");
181 RTPrintf("mandatory");
182 cFlags++;
183 }
184 if (pa->uKeyFlags & VD_CFGKEY_EXPERT)
185 {
186 if (cFlags)
187 RTPrintf(",");
188 RTPrintf("expert");
189 cFlags++;
190 }
191 RTPrintf(")");
192 pa++;
193 }
194 if (pa == aVDInfo[i].paConfigInfo)
195 RTPrintf("<EMPTY>");
196 }
197 else
198 RTPrintf("<NONE>");
199 RTPrintf("\n");
200
201 PVDINTERFACE pVDIfs = NULL;
202 VDINTERFACECONFIG ic;
203
204 ic.pfnAreKeysValid = tstAreKeysValid;
205 ic.pfnQuerySize = tstQuerySize;
206 ic.pfnQuery = tstQuery;
207
208 rc = VDInterfaceAdd(&ic.Core, "tstVD-2_Config", VDINTERFACETYPE_CONFIG,
209 NULL, sizeof(VDINTERFACECONFIG), &pVDIfs);
210 AssertRC(rc);
211
212 char *pszLocation, *pszName;
213 rc = aVDInfo[i].pfnComposeLocation(pVDIfs, &pszLocation);
214 CHECK("pfnComposeLocation()");
215 if (pszLocation)
216 {
217 RTMemFree(pszLocation);
218 if (aVDInfo[i].uBackendCaps & VD_CAP_FILE)
219 {
220 RTPrintf("Non-NULL location returned for file-based backend!\n");
221 return VERR_INTERNAL_ERROR;
222 }
223 }
224 rc = aVDInfo[i].pfnComposeName(pVDIfs, &pszName);
225 CHECK("pfnComposeName()");
226 if (pszName)
227 {
228 RTMemFree(pszName);
229 if (aVDInfo[i].uBackendCaps & VD_CAP_FILE)
230 {
231 RTPrintf("Non-NULL name returned for file-based backend!\n");
232 return VERR_INTERNAL_ERROR;
233 }
234 }
235 }
236
237#undef CHECK
238 return 0;
239}
240
241
242int main(int argc, char *argv[])
243{
244 int rc;
245
246 RTR3InitExe(argc, &argv, 0);
247 RTPrintf("tstVD-2: TESTING...\n");
248
249 rc = tstVDBackendInfo();
250 if (RT_FAILURE(rc))
251 {
252 RTPrintf("tstVD-2: getting backend info test failed! rc=%Rrc\n", rc);
253 g_cErrors++;
254 }
255
256 rc = VDShutdown();
257 if (RT_FAILURE(rc))
258 {
259 RTPrintf("tstVD-2: unloading backends failed! rc=%Rrc\n", rc);
260 g_cErrors++;
261 }
262 /*
263 * Summary
264 */
265 if (!g_cErrors)
266 RTPrintf("tstVD-2: SUCCESS\n");
267 else
268 RTPrintf("tstVD-2: FAILURE - %d errors\n", g_cErrors);
269
270 return !!g_cErrors;
271}
272
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