VirtualBox

source: vbox/trunk/src/VBox/Main/testcase/tstGuestCtrlParseBuffer.cpp@ 38395

Last change on this file since 38395 was 38395, checked in by vboxsync, 14 years ago

GuestCtrl: Update.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.5 KB
Line 
1/* $Id: tstGuestCtrlParseBuffer.cpp 38395 2011-08-10 11:48:29Z vboxsync $ */
2
3/** @file
4 *
5 * Output stream parsing test cases.
6 */
7
8/*
9 * Copyright (C) 2011 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.215389.xyz. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20#include <stdio.h>
21#include <stdlib.h>
22
23#include "../include/GuestCtrlImplPrivate.h"
24
25using namespace com;
26
27#define LOG_ENABLED
28#define LOG_GROUP LOG_GROUP_MAIN
29#define LOG_INSTANCE NULL
30#include <VBox/log.h>
31
32#include <iprt/test.h>
33#include <iprt/stream.h>
34
35#ifndef BYTE
36# define BYTE uint8_t
37#endif
38
39typedef struct VBOXGUESTCTRL_BUFFER_VALUE
40{
41 char *pszValue;
42} VBOXGUESTCTRL_BUFFER_VALUE, *PVBOXGUESTCTRL_BUFFER_VALUE;
43typedef std::map< RTCString, VBOXGUESTCTRL_BUFFER_VALUE > GuestBufferMap;
44typedef std::map< RTCString, VBOXGUESTCTRL_BUFFER_VALUE >::iterator GuestBufferMapIter;
45typedef std::map< RTCString, VBOXGUESTCTRL_BUFFER_VALUE >::const_iterator GuestBufferMapIterConst;
46
47char szUnterm1[] = { 'a', 's', 'd', 'f' };
48char szUnterm2[] = { 'f', 'o', 'o', '3', '=', 'b', 'a', 'r', '3' };
49
50static struct
51{
52 const char *pbData;
53 size_t cbData;
54 uint32_t uOffsetStart;
55 uint32_t uOffsetAfter;
56 uint32_t uMapElements;
57 int iResult;
58} aTests[] =
59{
60 /*
61 * Single object parsing.
62 * An object is represented by one or multiple key=value pairs which are
63 * separated by a single "\0". If this termination is missing it will be assumed
64 * that we need to collect more data to do a successful parsing.
65 */
66
67 /* Invalid stuff. */
68 { NULL, 0, 0, 0, 0, VERR_INVALID_POINTER },
69 { NULL, 512, 0, 0, 0, VERR_INVALID_POINTER },
70 { "", 0, 0, 0, 0, VERR_INVALID_PARAMETER },
71 { "", 0, 0, 0, 0, VERR_INVALID_PARAMETER },
72 { "foo=bar1", 0, 0, 0, 0, VERR_INVALID_PARAMETER },
73 { "foo=bar2", 0, 50, 50, 0, VERR_INVALID_PARAMETER },
74 /* Empty buffers. */
75 { "", 1, 0, 1, 0, VINF_SUCCESS },
76 { "\0", 1, 0, 1, 0, VINF_SUCCESS },
77 /* Unterminated values (missing "\0"). */
78 { "test1", sizeof("test1"), 0, 0, 0, VERR_MORE_DATA },
79 { "test2=", sizeof("test2="), 0, 0, 0, VERR_MORE_DATA },
80 { "test3=test3", sizeof("test3=test3"), 0, 0, 0, VERR_MORE_DATA },
81 { "test4=test4\0t41", sizeof("test4=test4\0t41"), 0, sizeof("test4=test4\0") - 1, 1, VERR_MORE_DATA },
82 { "test5=test5\0t51=t51", sizeof("test5=test5\0t51=t51"), 0, sizeof("test5=test5\0") - 1, 1, VERR_MORE_DATA },
83 /* Next block unterminated. */
84 { "t51=t51\0t52=t52\0\0t53=t53", sizeof("t51=t51\0t52=t52\0\0t53=t53"), 0, sizeof("t51=t51\0t52=t52\0") - 1, 2, VINF_SUCCESS },
85 { "test6=test6\0\0t61=t61", sizeof("test6=test6\0\0t61=t61"), 0, sizeof("test6=test6\0") - 1, 1, VINF_SUCCESS },
86 /* Good stuff. */
87 { "test61=\0test611=test611\0", sizeof("test61=\0test611=test611\0"), 0, sizeof("test61=\0test611=test611\0") - 1, 2, VINF_SUCCESS },
88 { "test7=test7\0\0", sizeof("test7=test7\0\0"), 0, sizeof("test7=test7\0") - 1, 1, VINF_SUCCESS },
89 { "test8=test8\0t81=t81\0\0", sizeof("test8=test8\0t81=t81\0\0"), 0, sizeof("test8=test8\0t81=t81\0") - 1, 2, VINF_SUCCESS },
90 /* Good stuff, but with a second block -- should be *not* taken into account since
91 * we're only interested in parsing/handling the first object. */
92 { "t9=t9\0t91=t91\0\0t92=t92\0\0", sizeof("t9=t9\0t91=t91\0\0t92=t92\0\0"), 0, sizeof("t9=t9\0t91=t91\0") - 1, 2, VINF_SUCCESS }
93};
94
95static struct
96{
97 const char *pbData;
98 size_t cbData;
99 /** Number of data blocks retrieved. These are separated by "\0\0". */
100 uint32_t uNumBlocks;
101 /** Overall result when done parsing. */
102 int iResult;
103} aTests2[] =
104{
105 /* No blocks. */
106 { "\0\0\0\0", sizeof("\0\0\0\0"), 0, VERR_NO_DATA },
107 /* Good stuff. */
108 { "\0b1=b1\0\0", sizeof("\0b1=b1\0\0"), 1, VERR_NO_DATA },
109 { "b1=b1\0\0", sizeof("b1=b1\0\0"), 1, VERR_NO_DATA },
110 { "b1=b1\0b2=b2\0\0", sizeof("b1=b1\0b2=b2\0\0"), 1, VERR_NO_DATA },
111 { "b1=b1\0b2=b2\0\0\0", sizeof("b1=b1\0b2=b2\0\0\0"), 1, VERR_NO_DATA }
112};
113
114int main()
115{
116 RTTEST hTest;
117 int rc = RTTestInitAndCreate("tstParseBuffer", &hTest);
118 if (rc)
119 return rc;
120 RTTestBanner(hTest);
121
122 RTTestIPrintf(RTTESTLVL_DEBUG, "Initializing COM...\n");
123 rc = com::Initialize();
124 if (FAILED(rc))
125 {
126 RTPrintf("ERROR: failed to initialize COM!\n");
127 return rc;
128 }
129
130 RTTestIPrintf(RTTESTLVL_INFO, "Doing basic tests ...\n");
131
132 if (sizeof("sizecheck") != 10)
133 RTTestFailed(hTest, "Basic size test #1 failed (%u <-> 10)", sizeof("sizecheck"));
134 if (sizeof("off=rab") != 8)
135 RTTestFailed(hTest, "Basic size test #2 failed (%u <-> 7)", sizeof("off=rab"));
136 if (sizeof("off=rab\0\0") != 10)
137 RTTestFailed(hTest, "Basic size test #3 failed (%u <-> 10)", sizeof("off=rab\0\0"));
138
139 RTTestIPrintf(RTTESTLVL_INFO, "Doing line tests ...\n");
140
141 unsigned iTest = 0;
142 for (iTest; iTest < RT_ELEMENTS(aTests); iTest++)
143 {
144 RTTestIPrintf(RTTESTLVL_DEBUG, "=> Test #%u\n", iTest);
145
146 GuestProcessStream stream;
147 int iResult = stream.AddData((BYTE*)aTests[iTest].pbData, aTests[iTest].cbData);
148 if (RT_SUCCESS(iResult))
149 {
150 GuestProcessStreamBlock curBlock;
151 iResult = stream.ParseBlock(curBlock);
152 if (iResult != aTests[iTest].iResult)
153 {
154 RTTestFailed(hTest, "\tReturned %Rrc, expected %Rrc",
155 iResult, aTests[iTest].iResult);
156 }
157 else if (stream.GetOffset() != aTests[iTest].uOffsetAfter)
158 {
159 RTTestFailed(hTest, "\tOffset %u wrong, expected %u",
160 stream.GetOffset(), aTests[iTest].uOffsetAfter);
161 }
162 else if (iResult == VERR_MORE_DATA)
163 {
164 RTTestIPrintf(RTTESTLVL_DEBUG, "\tMore data (Offset: %u)\n", stream.GetOffset());
165 }
166
167 if ( ( RT_SUCCESS(iResult)
168 || iResult == VERR_MORE_DATA))
169 {
170 if (curBlock.GetCount() != aTests[iTest].uMapElements)
171 {
172 RTTestFailed(hTest, "\tMap has %u elements, expected %u",
173 curBlock.GetCount(), aTests[iTest].uMapElements);
174 }
175 }
176
177 /* There is remaining data left in the buffer (which needs to be merged
178 * with a following buffer) -- print it. */
179 uint32_t uOffset = stream.GetOffset();
180 size_t uToWrite = aTests[iTest].cbData - uOffset;
181 if (uToWrite)
182 {
183 const char *pszRemaining = aTests[iTest].pbData;
184 RTTestIPrintf(RTTESTLVL_DEBUG, "\tRemaining (%u):\n", uToWrite);
185 RTStrmWriteEx(g_pStdOut, &aTests[iTest].pbData[uOffset], uToWrite - 1, NULL);
186 }
187 }
188 }
189
190 RTTestIPrintf(RTTESTLVL_INFO, "Doing block tests ...\n");
191
192 iTest = 0;
193 for (iTest; iTest < RT_ELEMENTS(aTests2); iTest++)
194 {
195 RTTestIPrintf(RTTESTLVL_DEBUG, "=> Block test #%u\n", iTest);
196
197 GuestProcessStream stream;
198 int iResult = stream.AddData((BYTE*)aTests2[iTest].pbData, aTests2[iTest].cbData);
199 if (RT_SUCCESS(iResult))
200 {
201 uint32_t uNumBlocks = 0;
202 uint8_t uSafeCouunter = 0;
203 do
204 {
205 GuestProcessStreamBlock curBlock;
206 iResult = stream.ParseBlock(curBlock);
207 RTTestIPrintf(RTTESTLVL_DEBUG, "\tReturned with %Rrc\n", iResult);
208 if (RT_SUCCESS(iResult))
209 {
210 /* Only count block which have at least one pair. */
211 if (curBlock.GetCount())
212 uNumBlocks++;
213 }
214 if (uSafeCouunter++ > 32)
215 break;
216 } while (RT_SUCCESS(iResult));
217
218 if (iResult != aTests2[iTest].iResult)
219 {
220 RTTestFailed(hTest, "\tReturned %Rrc, expected %Rrc",
221 iResult, aTests2[iTest].iResult);
222 }
223 else if (uNumBlocks != aTests2[iTest].uNumBlocks)
224 {
225 RTTestFailed(hTest, "\tReturned %u blocks, expected %u\n",
226 uNumBlocks, aTests2[iTest].uNumBlocks);
227 }
228 }
229 else
230 RTTestFailed(hTest, "\tAdding data failed with %Rrc", iResult);
231 }
232
233 RTTestIPrintf(RTTESTLVL_DEBUG, "Shutting down COM...\n");
234 com::Shutdown();
235
236 /*
237 * Summary.
238 */
239 return RTTestSummaryAndDestroy(hTest);
240}
241
Note: See TracBrowser for help on using the repository browser.

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