VirtualBox

source: vbox/trunk/src/VBox/Main/testcase/tstUnattendedScript.cpp@ 94521

Last change on this file since 94521 was 94075, checked in by vboxsync, 2 years ago

Main/Unattended: ​bugref:9781. Adding a property to IUnattended to indicate if unattended install is possible.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.6 KB
Line 
1/* $Id: tstUnattendedScript.cpp 94075 2022-03-03 13:59:09Z vboxsync $ */
2/** @file
3 * tstUnattendedScript - testcases for UnattendedScript.
4 */
5
6/*
7 * Copyright (C) 2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#include "UnattendedScript.h"
23
24#include <VBox/com/VirtualBox.h>
25#include <VBox/com/errorprint.h>
26
27#include <iprt/file.h>
28#include <iprt/path.h>
29#include <iprt/test.h>
30#include <iprt/stream.h>
31
32#include "VirtualBoxBase.h"
33#include "UnattendedImpl.h"
34#include "UnattendedScript.h"
35#include "VirtualBoxImpl.h"
36#include "MachineImpl.h"
37
38using namespace std;
39
40
41/*********************************************************************************************************************************
42* Unattended Stub Implementation *
43*********************************************************************************************************************************/
44Unattended::Unattended()
45 : mhThreadReconfigureVM(NIL_RTNATIVETHREAD), mfRtcUseUtc(false), mfGuestOs64Bit(false)
46 , mpInstaller(NULL), mpTimeZoneInfo(NULL), mfIsDefaultAuxiliaryBasePath(true), mfDoneDetectIsoOS(false)
47{
48 mStrUser = "vboxuser";
49 mStrPassword = "changeme";
50 mStrFullUserName = "VBox & VBox;";
51 mStrProductKey = "911";
52 mStrIsoPath = "/iso/path/file.iso";
53 mStrAdditionsIsoPath = "/iso/path/addition.iso";
54 mfInstallGuestAdditions = true;
55 mfInstallTestExecService = true;
56 mStrValidationKitIsoPath = "/iso/path/valkit.iso";
57 mStrTimeZone = "cet";
58 mpTimeZoneInfo = NULL;
59 mStrLocale = "dk_DK";
60 mStrLanguage = "dk";
61 mStrCountry = "DK";
62 //mPackageSelectionAdjustments = "minimal";
63 mStrHostname = "my-extra-long-name.hostname.com";
64 mStrAuxiliaryBasePath = "/aux/path/pfx-";
65 mfIsDefaultAuxiliaryBasePath = false;
66 midxImage = 42;
67 mStrScriptTemplatePath = "/path/to/script-template.file";
68 mStrPostInstallScriptTemplatePath = "/path/to/post-install-template.file";
69 mStrPostInstallCommand = "/bin/post-install-command arg1 arg2 --amp=& --lt=< --gt=> --dq-word=\"word\" --sq-word='word'";
70 mStrExtraInstallKernelParameters = "extra=kernel parameters quiet amp=& lt=< gt=>";
71 mStrProxy = "http://proxy.intranet.com:443";
72
73 mfDoneDetectIsoOS = true;
74 mStrDetectedOSTypeId = "MyOSTypeId";
75 mStrDetectedOSVersion = "3.4.2";
76 mStrDetectedOSFlavor = "server";
77 //mDetectedOSLanguages = "en_UK"
78 mStrDetectedOSHints = "nudge nudge wink wink";
79}
80
81Unattended::~Unattended()
82{
83}
84
85HRESULT Unattended::FinalConstruct()
86{
87 return BaseFinalConstruct();
88}
89
90void Unattended::FinalRelease()
91{
92 uninit();
93 BaseFinalRelease();
94}
95
96void Unattended::uninit()
97{
98}
99
100HRESULT Unattended::initUnattended(VirtualBox *aParent)
101{
102 unconst(mParent) = aParent;
103 return S_OK;
104}
105
106HRESULT Unattended::detectIsoOS()
107{
108 return E_NOTIMPL;
109}
110
111
112HRESULT Unattended::prepare()
113{
114 return E_NOTIMPL;
115}
116
117HRESULT Unattended::constructMedia()
118{
119 return E_NOTIMPL;
120}
121
122HRESULT Unattended::reconfigureVM()
123{
124 return E_NOTIMPL;
125}
126
127HRESULT Unattended::done()
128{
129 return E_NOTIMPL;
130}
131
132HRESULT Unattended::getIsoPath(com::Utf8Str &isoPath)
133{
134 RT_NOREF(isoPath);
135 return E_NOTIMPL;
136}
137
138HRESULT Unattended::setIsoPath(const com::Utf8Str &isoPath)
139{
140 RT_NOREF(isoPath);
141 return E_NOTIMPL;
142}
143
144HRESULT Unattended::getUser(com::Utf8Str &user)
145{
146 RT_NOREF(user);
147 return E_NOTIMPL;
148}
149
150
151HRESULT Unattended::setUser(const com::Utf8Str &user)
152{
153 RT_NOREF(user);
154 return E_NOTIMPL;
155}
156
157HRESULT Unattended::getPassword(com::Utf8Str &password)
158{
159 RT_NOREF(password);
160 return E_NOTIMPL;
161}
162
163HRESULT Unattended::setPassword(const com::Utf8Str &password)
164{
165 RT_NOREF(password);
166 return E_NOTIMPL;
167}
168
169HRESULT Unattended::getFullUserName(com::Utf8Str &fullUserName)
170{
171 RT_NOREF(fullUserName);
172 return E_NOTIMPL;
173}
174
175HRESULT Unattended::setFullUserName(const com::Utf8Str &fullUserName)
176{
177 RT_NOREF(fullUserName);
178 return E_NOTIMPL;
179}
180
181HRESULT Unattended::getProductKey(com::Utf8Str &productKey)
182{
183 RT_NOREF(productKey);
184 return E_NOTIMPL;
185}
186
187HRESULT Unattended::setProductKey(const com::Utf8Str &productKey)
188{
189 RT_NOREF(productKey);
190 return E_NOTIMPL;
191}
192
193HRESULT Unattended::getAdditionsIsoPath(com::Utf8Str &additionsIsoPath)
194{
195 RT_NOREF(additionsIsoPath);
196 return E_NOTIMPL;
197}
198
199HRESULT Unattended::setAdditionsIsoPath(const com::Utf8Str &additionsIsoPath)
200{
201 RT_NOREF(additionsIsoPath);
202 return E_NOTIMPL;
203}
204
205HRESULT Unattended::getInstallGuestAdditions(BOOL *installGuestAdditions)
206{
207 RT_NOREF(installGuestAdditions);
208 return E_NOTIMPL;
209}
210
211HRESULT Unattended::setInstallGuestAdditions(BOOL installGuestAdditions)
212{
213 RT_NOREF(installGuestAdditions);
214 return E_NOTIMPL;
215}
216
217HRESULT Unattended::getValidationKitIsoPath(com::Utf8Str &aValidationKitIsoPath)
218{
219 RT_NOREF(aValidationKitIsoPath);
220 return E_NOTIMPL;
221}
222
223HRESULT Unattended::setValidationKitIsoPath(const com::Utf8Str &aValidationKitIsoPath)
224{
225 RT_NOREF(aValidationKitIsoPath);
226 return E_NOTIMPL;
227}
228
229HRESULT Unattended::getInstallTestExecService(BOOL *aInstallTestExecService)
230{
231 RT_NOREF(aInstallTestExecService);
232 return E_NOTIMPL;
233}
234
235HRESULT Unattended::setInstallTestExecService(BOOL aInstallTestExecService)
236{
237 RT_NOREF(aInstallTestExecService);
238 return E_NOTIMPL;
239}
240
241HRESULT Unattended::getTimeZone(com::Utf8Str &aTimeZone)
242{
243 RT_NOREF(aTimeZone);
244 return E_NOTIMPL;
245}
246
247HRESULT Unattended::setTimeZone(const com::Utf8Str &aTimezone)
248{
249 RT_NOREF(aTimezone);
250 return E_NOTIMPL;
251}
252
253HRESULT Unattended::getLocale(com::Utf8Str &aLocale)
254{
255 RT_NOREF(aLocale);
256 return E_NOTIMPL;
257}
258
259HRESULT Unattended::setLocale(const com::Utf8Str &aLocale)
260{
261 RT_NOREF(aLocale);
262 return E_NOTIMPL;
263}
264
265HRESULT Unattended::getLanguage(com::Utf8Str &aLanguage)
266{
267 RT_NOREF(aLanguage);
268 return E_NOTIMPL;
269}
270
271HRESULT Unattended::setLanguage(const com::Utf8Str &aLanguage)
272{
273 RT_NOREF(aLanguage);
274 return E_NOTIMPL;
275}
276
277HRESULT Unattended::getCountry(com::Utf8Str &aCountry)
278{
279 RT_NOREF(aCountry);
280 return E_NOTIMPL;
281}
282
283HRESULT Unattended::setCountry(const com::Utf8Str &aCountry)
284{
285 RT_NOREF(aCountry);
286 return E_NOTIMPL;
287}
288
289HRESULT Unattended::getProxy(com::Utf8Str &aProxy)
290{
291 RT_NOREF(aProxy);
292 return E_NOTIMPL;
293}
294
295HRESULT Unattended::setProxy(const com::Utf8Str &aProxy)
296{
297 RT_NOREF(aProxy);
298 return E_NOTIMPL;
299}
300
301HRESULT Unattended::getPackageSelectionAdjustments(com::Utf8Str &aPackageSelectionAdjustments)
302{
303 RT_NOREF(aPackageSelectionAdjustments);
304 return E_NOTIMPL;
305}
306
307HRESULT Unattended::setPackageSelectionAdjustments(const com::Utf8Str &aPackageSelectionAdjustments)
308{
309 RT_NOREF(aPackageSelectionAdjustments);
310 return E_NOTIMPL;
311}
312
313HRESULT Unattended::getHostname(com::Utf8Str &aHostname)
314{
315 RT_NOREF(aHostname);
316 return E_NOTIMPL;
317}
318
319HRESULT Unattended::setHostname(const com::Utf8Str &aHostname)
320{
321 RT_NOREF(aHostname);
322 return E_NOTIMPL;
323}
324
325HRESULT Unattended::getAuxiliaryBasePath(com::Utf8Str &aAuxiliaryBasePath)
326{
327 RT_NOREF(aAuxiliaryBasePath);
328 return E_NOTIMPL;
329}
330
331HRESULT Unattended::setAuxiliaryBasePath(const com::Utf8Str &aAuxiliaryBasePath)
332{
333 RT_NOREF(aAuxiliaryBasePath);
334 return E_NOTIMPL;
335}
336
337HRESULT Unattended::getImageIndex(ULONG *index)
338{
339 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
340 *index = midxImage;
341 return S_OK;
342}
343
344HRESULT Unattended::setImageIndex(ULONG index)
345{
346 RT_NOREF(index);
347 return E_NOTIMPL;
348}
349
350HRESULT Unattended::getMachine(ComPtr<IMachine> &aMachine)
351{
352 RT_NOREF(aMachine);
353 return E_NOTIMPL;
354}
355
356HRESULT Unattended::setMachine(const ComPtr<IMachine> &aMachine)
357{
358 RT_NOREF(aMachine);
359 return E_NOTIMPL;
360}
361
362HRESULT Unattended::getScriptTemplatePath(com::Utf8Str &aScriptTemplatePath)
363{
364 RT_NOREF(aScriptTemplatePath);
365 return E_NOTIMPL;
366}
367
368HRESULT Unattended::setScriptTemplatePath(const com::Utf8Str &aScriptTemplatePath)
369{
370 RT_NOREF(aScriptTemplatePath);
371 return E_NOTIMPL;
372
373}
374
375HRESULT Unattended::getPostInstallScriptTemplatePath(com::Utf8Str &aPostInstallScriptTemplatePath)
376{
377 RT_NOREF(aPostInstallScriptTemplatePath);
378 return E_NOTIMPL;
379}
380
381HRESULT Unattended::setPostInstallScriptTemplatePath(const com::Utf8Str &aPostInstallScriptTemplatePath)
382{
383 RT_NOREF(aPostInstallScriptTemplatePath);
384 return E_NOTIMPL;
385}
386
387HRESULT Unattended::getPostInstallCommand(com::Utf8Str &aPostInstallCommand)
388{
389 RT_NOREF(aPostInstallCommand);
390 return E_NOTIMPL;
391}
392
393HRESULT Unattended::setPostInstallCommand(const com::Utf8Str &aPostInstallCommand)
394{
395 RT_NOREF(aPostInstallCommand);
396 return E_NOTIMPL;
397}
398
399HRESULT Unattended::getExtraInstallKernelParameters(com::Utf8Str &aExtraInstallKernelParameters)
400{
401 RT_NOREF(aExtraInstallKernelParameters);
402 return E_NOTIMPL;
403}
404
405HRESULT Unattended::setExtraInstallKernelParameters(const com::Utf8Str &aExtraInstallKernelParameters)
406{
407 RT_NOREF(aExtraInstallKernelParameters);
408 return E_NOTIMPL;
409}
410
411HRESULT Unattended::getDetectedOSTypeId(com::Utf8Str &aDetectedOSTypeId)
412{
413 RT_NOREF(aDetectedOSTypeId);
414 return E_NOTIMPL;
415}
416
417HRESULT Unattended::getDetectedOSVersion(com::Utf8Str &aDetectedOSVersion)
418{
419 RT_NOREF(aDetectedOSVersion);
420 return E_NOTIMPL;
421}
422
423HRESULT Unattended::getDetectedOSFlavor(com::Utf8Str &aDetectedOSFlavor)
424{
425 RT_NOREF(aDetectedOSFlavor);
426 return E_NOTIMPL;
427}
428
429HRESULT Unattended::getDetectedOSLanguages(com::Utf8Str &aDetectedOSLanguages)
430{
431 RT_NOREF(aDetectedOSLanguages);
432 return E_NOTIMPL;
433}
434
435HRESULT Unattended::getDetectedOSHints(com::Utf8Str &aDetectedOSHints)
436{
437 RT_NOREF(aDetectedOSHints);
438 return E_NOTIMPL;
439}
440
441HRESULT Unattended::getDetectedImageNames(std::vector<com::Utf8Str> &aDetectedImageNames)
442{
443 RT_NOREF(aDetectedImageNames);
444 return E_NOTIMPL;
445}
446
447HRESULT Unattended::getDetectedImageIndices(std::vector<ULONG> &aDetectedImageIndices)
448{
449 RT_NOREF(aDetectedImageIndices);
450 return E_NOTIMPL;
451}
452
453HRESULT Unattended::getIsUnattendedInstallSupported(BOOL *aIsUnattendedInstallSupported)
454{
455 RT_NOREF(aIsUnattendedInstallSupported);
456 return E_NOTIMPL;
457}
458
459/*
460 * Getters that the installer and script classes can use.
461 */
462Utf8Str const &Unattended::i_getIsoPath() const
463{
464 return mStrIsoPath;
465}
466
467Utf8Str const &Unattended::i_getUser() const
468{
469 return mStrUser;
470}
471
472Utf8Str const &Unattended::i_getPassword() const
473{
474 return mStrPassword;
475}
476
477Utf8Str const &Unattended::i_getFullUserName() const
478{
479 return mStrFullUserName.isNotEmpty() ? mStrFullUserName : mStrUser;
480}
481
482Utf8Str const &Unattended::i_getProductKey() const
483{
484 return mStrProductKey;
485}
486
487Utf8Str const &Unattended::i_getProxy() const
488{
489 return mStrProxy;
490}
491
492Utf8Str const &Unattended::i_getAdditionsIsoPath() const
493{
494 return mStrAdditionsIsoPath;
495}
496
497bool Unattended::i_getInstallGuestAdditions() const
498{
499 return mfInstallGuestAdditions;
500}
501
502Utf8Str const &Unattended::i_getValidationKitIsoPath() const
503{
504 return mStrValidationKitIsoPath;
505}
506
507bool Unattended::i_getInstallTestExecService() const
508{
509 return mfInstallTestExecService;
510}
511
512Utf8Str const &Unattended::i_getTimeZone() const
513{
514 return mStrTimeZone;
515}
516
517PCRTTIMEZONEINFO Unattended::i_getTimeZoneInfo() const
518{
519 return mpTimeZoneInfo;
520}
521
522Utf8Str const &Unattended::i_getLocale() const
523{
524 return mStrLocale;
525}
526
527Utf8Str const &Unattended::i_getLanguage() const
528{
529 return mStrLanguage;
530}
531
532Utf8Str const &Unattended::i_getCountry() const
533{
534 return mStrCountry;
535}
536
537bool Unattended::i_isMinimalInstallation() const
538{
539 size_t i = mPackageSelectionAdjustments.size();
540 while (i-- > 0)
541 if (mPackageSelectionAdjustments[i].equals("minimal"))
542 return true;
543 return false;
544}
545
546Utf8Str const &Unattended::i_getHostname() const
547{
548 return mStrHostname;
549}
550
551Utf8Str const &Unattended::i_getAuxiliaryBasePath() const
552{
553 return mStrAuxiliaryBasePath;
554}
555
556ULONG Unattended::i_getImageIndex() const
557{
558 return midxImage;
559}
560
561Utf8Str const &Unattended::i_getScriptTemplatePath() const
562{
563 return mStrScriptTemplatePath;
564}
565
566Utf8Str const &Unattended::i_getPostInstallScriptTemplatePath() const
567{
568 return mStrPostInstallScriptTemplatePath;
569}
570
571Utf8Str const &Unattended::i_getPostInstallCommand() const
572{
573 return mStrPostInstallCommand;
574}
575
576Utf8Str const &Unattended::i_getAuxiliaryInstallDir() const
577{
578 static Utf8Str s_strAuxInstallDir("/aux/install/dir");
579 return s_strAuxInstallDir;
580}
581
582Utf8Str const &Unattended::i_getExtraInstallKernelParameters() const
583{
584 return mStrExtraInstallKernelParameters;
585}
586
587bool Unattended::i_isRtcUsingUtc() const
588{
589 return mfRtcUseUtc;
590}
591
592bool Unattended::i_isGuestOs64Bit() const
593{
594 return mfGuestOs64Bit;
595}
596
597bool Unattended::i_isFirmwareEFI() const
598{
599 return menmFirmwareType != FirmwareType_BIOS;
600}
601
602Utf8Str const &Unattended::i_getDetectedOSVersion()
603{
604 return mStrDetectedOSVersion;
605}
606
607
608/*********************************************************************************************************************************
609* The Testcase *
610*********************************************************************************************************************************/
611
612static bool loadFileAsString(const char *pszFilename, Utf8Str &rstrContent)
613{
614 rstrContent.setNull();
615
616 char szPath[RTPATH_MAX];
617 RTTESTI_CHECK_RC_RET(RTPathExecDir(szPath, sizeof(szPath)), VINF_SUCCESS, false);
618 RTTESTI_CHECK_RC_RET(RTPathAppend(szPath, sizeof(szPath), pszFilename), VINF_SUCCESS, false);
619
620 RTFILE hFile;
621 RTTESTI_CHECK_RC_RET(RTFileOpen(&hFile, szPath, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE), VINF_SUCCESS, false);
622
623 uint64_t cbFile = 0;
624 RTTESTI_CHECK_RC_RET(RTFileQuerySize(hFile, &cbFile), VINF_SUCCESS, false);
625
626 rstrContent.reserve((size_t)cbFile + 1);
627 RTTESTI_CHECK_RC_RET(RTFileRead(hFile, rstrContent.mutableRaw(), (size_t)cbFile, NULL), VINF_SUCCESS, false);
628 rstrContent.mutableRaw()[cbFile] = '\0';
629 rstrContent.jolt();
630
631 RTTESTI_CHECK_RC_RET(RTFileClose(hFile), VINF_SUCCESS, false);
632
633 return true;
634}
635
636static void doTest1()
637{
638 RTTestISub("tstUnattendedScript-1.template");
639
640 /* Create the parent class instance: */
641 ComObjPtr<Unattended> ptrParent;
642 HRESULT hrc = ptrParent.createObject();
643 RTTESTI_CHECK_MSG_RETV(SUCCEEDED(hrc), ("hrc=%Rhrc\n", hrc));
644
645 /* Instantiate the script editor. */
646 UnattendedScriptTemplate Tmpl(ptrParent, "template.ext", "file.ext");
647#define CHECK_HRESULT(a_Expr) do { \
648 HRESULT hrcThis = a_Expr; \
649 if (SUCCEEDED(hrcThis)) break; \
650 RTTestIFailed("line %d: %s -> %Rhrc", __LINE__, #a_Expr, hrcThis); \
651 GlueHandleComError(ptrParent, NULL, hrcThis, NULL, __LINE__); \
652 } while (0)
653
654 /* Load the exercise script. */
655 char szPath[RTPATH_MAX];
656 RTTESTI_CHECK_RC_RETV(RTPathExecDir(szPath, sizeof(szPath)), VINF_SUCCESS);
657 RTTESTI_CHECK_RC_RETV(RTPathAppend(szPath, sizeof(szPath), "tstUnattendedScript-1.template"), VINF_SUCCESS);
658 CHECK_HRESULT(Tmpl.read(szPath));
659
660 /* Save the template to string. */
661 Utf8Str strActual;
662 CHECK_HRESULT(Tmpl.saveToString(strActual));
663
664 /* Load the expected result. */
665 Utf8Str strExpected;
666 RTTESTI_CHECK_RETV(loadFileAsString("tstUnattendedScript-1.expected", strExpected));
667
668 /* Compare the two. */
669 if (strExpected != strActual)
670 {
671 RTTestIFailed("Output does not match tstUnattendedScript-1.expect!");
672 RTTestIFailureDetails("------ BEGIN OUTPUT ------\n");
673 RTStrmWrite(g_pStdErr, strActual.c_str(), strActual.length());
674 RTTestIFailureDetails("------- END OUTPUT -------\n");
675
676 RTCList<RTCString, RTCString *> const lstActual = strActual.split("\n");
677 RTCList<RTCString, RTCString *> const lstExpected = strExpected.split("\n");
678 size_t const cLines = RT_MIN(lstActual.size(), lstExpected.size());
679 for (size_t i = 0; i < cLines; i++)
680 if (lstActual[i] != lstExpected[i])
681 {
682 RTTestIFailureDetails("First difference on line %u:\n%s\nexpected:\n%s\n",
683 i + 1, lstActual[i].c_str(), lstExpected[i].c_str());
684 break;
685 }
686 }
687}
688
689int main()
690{
691 RTTEST hTest;
692 RTEXITCODE rcExit = RTTestInitAndCreate("tstUnattendedScript", &hTest);
693 if (rcExit != RTEXITCODE_SUCCESS)
694 return rcExit;
695
696#ifdef RT_OS_WINDOWS
697 /*ATL::CComModule *g_pAtlComModule = */ new(ATL::CComModule);
698#endif
699
700 doTest1();
701
702 return RTTestSummaryAndDestroy(hTest);
703}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use