SMBIOS Library
testPlatform.cpp
Go to the documentation of this file.
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  * vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=c:cindent:textwidth=0:
3  *
4  * Copyright (C) 2005 Dell Inc.
5  * by Michael Brown <Michael_E_Brown@dell.com>
6  * Licensed under the Open Software License version 2.1
7  *
8  * Alternatively, you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published
10  * by the Free Software Foundation; either version 2 of the License,
11  * or (at your option) any later version.
12 
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  */
18 
19 // compat header should always be first header if including system headers
20 #include "smbios/compat.h"
21 
22 #include <iomanip>
23 #include <fstream>
24 #include <string.h>
25 
26 #include "testPlatform.h"
27 #include "smbios/SmbiosDefs.h"
28 
29 // specific to unit tests. Users do not need to include this,
30 // so it is not in testPlatform.h
31 #include "smbios/IMemory.h"
32 #include "smbios/ISmi.h"
33 #include "smbios/IObserver.h"
34 
35 #include "smbios/version.h"
36 
37 using namespace std;
38 
39 // Note:
40 // Except for , there are no "using namespace XXXX;" statements
41 // here... on purpose. We want to ensure that while reading this code that
42 // it is extremely obvious where each function is coming from.
43 //
44 // This leads to verbose code in some instances, but that is fine for
45 // these purposes.
46 
47 // Register the test
49 
50 void copyFile( string dstFile, string srcFile )
51 {
52  ifstream src(srcFile.c_str(), ios_base::binary);
53  ofstream dst(dstFile.c_str(), ios_base::out | ios_base::binary | ios_base::trunc);
54 
55  char ch;
56  while( src.get(ch)) dst.put(ch);
57 
58  if( !src.eof() || !dst ) throw exception();
59 }
60 
61 bool fileExists(string fileName)
62 {
63  FILE *fh=0;
64  fh=fopen(fileName.c_str(), "rb");
65  if(!fh)
66  return false;
67 
68  fclose(fh);
69  return true;
70 }
71 
73 {
74  string programDirname = getCppunitTopDirectory();
75  string writeDirectory = getWritableDirectory();
76 
77  string testInput = programDirname + getTestDirectory() + "/testInput.xml";
78  if(!fileExists(testInput))
79  testInput = getTestDirectory() + "/testInput.xml";
80 
81  // copy the memdump.dat file. We do not write to it, but rw open will fail
82  // if we do not copy it
83  string memdumpOrigFile = programDirname + getTestDirectory() + "/memdump.dat";
84  if(!fileExists(memdumpOrigFile))
85  memdumpOrigFile = getTestDirectory() + "/memdump.dat";
86  string memdumpCopyFile = writeDirectory + "/memdump-copy.dat";
87  copyFile( memdumpCopyFile, memdumpOrigFile );
88 
89  // copy the CMOS file. We are going to write to it and do not wan to mess up
90  // the pristine unit test version
91  string cmosOrigFile = programDirname + getTestDirectory() + "/cmos.dat";
92  if(!fileExists(cmosOrigFile))
93  cmosOrigFile = getTestDirectory() + "/cmos.dat";
94  string cmosCopyFile = writeDirectory + "/cmos-copy.dat";
95  copyFile( cmosCopyFile, cmosOrigFile );
96 
97  // Smi output file.
98  string smiOutput = writeDirectory + "/smi-output.dat";
99 
100  // normal users of the smbios classes need not
101  // set the four parameters below. They should all be set inside the factory
102  // properly by default. We override stuff here to have
103  // the smbios, cmos, etc classes use file dumps instead of
104  // real memory/cmos/etc.
105  smbios::SmbiosFactory::getFactory()->setParameter("memFile", memdumpCopyFile);
108 
109  cmos:: CmosRWFactory::getFactory()->setParameter("cmosMapFile", cmosCopyFile);
111 
112  memory::MemoryFactory::getFactory()->setParameter("memFile", memdumpCopyFile);
114 
115  smi::SmiFactory::getFactory()->setParameter("smiFile", smiOutput);
117 
118  doc = 0;
119  parser = 0;
120  InitXML();
121  parser = xmlutils::getParser();
122  compatXmlReadFile(parser, doc, testInput.c_str());
123 }
124 
126 {
127  // the factory is static. If we do not reset the factory, the next
128  // unit test may accidentally get the wrong objects.
129  // Lifetime rules: CmosTokenTable cannot live longer than the ISmbiosTable
130  // object used in its construction.
132 
134 
136 
138 
140 
141  if (parser)
142  xmlFreeParser(parser);
143 
144  if (doc)
145  xmlFreeDoc(doc);
146 
147  FiniXML();
148 }
149 
150 // checkSkipTest for Skipping known BIOS Bugs.
151 void
153 {
154  if(!doc)
155  return;
156 
157  try
158  {
160  XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *test = xmlutils::findElement(testsToSkip,"test","name",testName);
161 
162  if(test)
163  throw skip_test();
164  }
165  catch (const skip_test &)
166  {
167  throw;
168  }
169  catch (const exception &)
170  {
171  //Do Nothing
172  }
173 }
174 
175 //
176 // CMOS Token
177 //
178 
179 void
181 {
182  STD_TEST_START_CHECKSKIP(getTestName().c_str() << " ");
183 
184  smbios::TokenTableFactory *ttFactory;
186  const smbios::ITokenTable *tokenTable = ttFactory->getSingleton();
187 
188  smbios::ITokenTable::const_iterator token = tokenTable->begin();
189  while( token != tokenTable->end() )
190  {
191  (void) *token;
192  ++token;
193  }
194 
196  observer::IObservable *ob = dynamic_cast<observer::IObservable *>(cmos);
197  bool doUpdate = false;
198  if( ob )
199  ob->notify(&doUpdate);
200 
201  STD_TEST_END("");
202 }
203 
204 void
206 {
207  STD_TEST_START_CHECKSKIP(getTestName().c_str() << " ");
208 
209  smbios::TokenTableFactory *ttFactory;
211  smbios::ITokenTable *tokenTable = ttFactory->getSingleton();
212  const smbios::ITokenTable *tokenTableC = ttFactory->getSingleton();
213 
214  ASSERT_THROWS( (*tokenTable) ["la la la"], smbios::NotImplemented );
215  ASSERT_THROWS( (*tokenTableC)["la la la"], smbios::NotImplemented );
216 
217  // test [] on const table.
218  (void) tokenTableC[0xFE];
219 
220  ostringstream ost;
221  ost << *tokenTable << endl;
222  ost << *tokenTableC << endl;
223 
224  // test const iterator
225  smbios::ITokenTable::const_iterator tokenC = tokenTableC->begin();
226  while( tokenC != tokenTableC->end() )
227  {
228  (void) *tokenC;
229  (void) tokenC->isString();
230 
231  tokenC++;
232  }
233 
234  // refuse to write to cmos unless the checksum is correct
236  observer::IObservable *ob = dynamic_cast<observer::IObservable *>(cmos);
237  bool doUpdate = false;
238  if( ob )
239  ob->notify(&doUpdate);
240 
241  smbios::ITokenTable::iterator token = tokenTable->begin();
242  while( token != tokenTable->end() )
243  {
244  //cout << *token << endl;
245  if( token->isString() )
246  {
247  const char *testStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnop";
248  const u8 *testStrU8 = reinterpret_cast<const u8*>(testStr);
249  u8 *myStr=0;
250  u8 *myStr1=0;
251  try
252  {
253  // not really a valid test anymore since SMI tokens can be
254  // accessed as bit or string.
255  //ASSERT_THROWS( token->activate(), smbios::InvalidAccessMode );
256  //ASSERT_THROWS( token->isActive(), smbios::InvalidAccessMode );
257 
258  unsigned int size = token->getStringLength() + 1;
259 
260  myStr1 = new u8[ size ];
261  memset( myStr1, 0, size );
262 
263  try
264  {
265  token->getString( myStr1, size );
266  }
267  catch(const smi::UnhandledSmi &)
268  { /* if token is a smi token, cannot unit test. */
269  delete [] myStr1;
270  goto next_token;
271  }
272 
273  token->setString( testStrU8, strlen(testStr) + 1 );
274 
275  CPPUNIT_ASSERT( size <= strlen(testStr)+1 );
276 
277  myStr = new u8[ size ];
278  memset( myStr, 0, size );
279  token->getString( myStr, size );
280 
281  // return might be smaller, only compare up to what was stored.
282  if( 0 != memcmp( testStr, reinterpret_cast<char*>(myStr), size - 1 ) )
283  {
284  // FAILED
285  ostringstream ost;
286  ost << "String set on token failed." << endl;
287  ost << (*token) << endl;
288  ost << "Size of string to compare is: " << size-1 << endl;
289  ost << "Original data: (" << myStr1 << ")" << endl;
290  ost << "Wrote : (" << testStr << ")" << endl;
291  ost << "Read back : (" << myStr << ")" << endl;
292  CPPUNIT_FAIL( ost.str().c_str() );
293  }
294  }
295  catch(...)
296  {
297  delete [] myStr1;
298  delete [] myStr;
299  myStr1 = 0;
300  myStr = 0;
301  throw;
302  }
303  delete [] myStr1;
304  delete [] myStr;
305  myStr1 = 0;
306  myStr = 0;
307  }
308  else
309  {
310  try
311  {
312  token->activate();
313  }
314  catch(const smi::UnhandledSmi &)
315  { /* if token is a smi token, cannot unit test. */
316  goto next_token;
317  }
318  if( ! token->isActive() )
319  {
320  ostringstream ost;
321  ost << "Failed to SET bit token. Token data: " << endl;
322  ost << (*token);
323  CPPUNIT_FAIL( ost.str().c_str() );
324  }
325  // not really a valid test anymore since SMI tokens can be
326  // accessed as bit or string.
327  //ASSERT_THROWS( token->setString(0, 0), smbios::InvalidAccessMode );
328  //ASSERT_THROWS( token->getStringLength(), smbios::InvalidAccessMode );
329  }
330 
331 next_token:
332  // test post-increment behaves properly
333  smbios::ITokenTable::iterator before = token;
334  smbios::ITokenTable::iterator after = token++;
335  CPPUNIT_ASSERT( before == after );
336  }
337 
338  // recheck the checksums.
339  // ensure that we wrote correct checksums out
340  if( ob )
341  ob->notify(&doUpdate);
342 
343  STD_TEST_END("");
344 }
345 
346 
347 
348 //
349 // System Info
350 //
351 
352 
353 void
355 {
356  STD_TEST_START_CHECKSKIP(getTestName().c_str() << " ");
357 
358  int systemId = 0;
359  const char *systemName = 0;
360  const char *serviceTag = 0;
361  const char *assetTag = 0;
362  const char *biosVersion = 0;
363  const char *vendorName = 0;
364 
365  try
366  {
367  systemId = SMBIOSGetDellSystemId();
368  systemName = SMBIOSGetSystemName();
369  serviceTag = SMBIOSGetServiceTag();
370  assetTag = SMBIOSGetAssetTag();
371  biosVersion = SMBIOSGetBiosVersion();
372  vendorName = SMBIOSGetVendorName();
373 
374  int isDell = SMBIOSIsDellSystem();
375 
376  (void) systemId; //avoid unused var warning
377  (void) isDell; //avoid unused var warning
378 
379  //We should at least get an empty string from these
380  //methods. Never a null string.
381  CPPUNIT_ASSERT(systemId != 0);
382  CPPUNIT_ASSERT(systemName != 0);
383  //CPPUNIT_ASSERT(serviceTag != 0); // svc tag can legitimately be 0
384  //CPPUNIT_ASSERT(assetTag != 0); //This fails on latitude so we comment out for now.
385  CPPUNIT_ASSERT(biosVersion != 0);
386  CPPUNIT_ASSERT(vendorName != 0);
387  }
388  catch(...)
389  {
390  SMBIOSFreeMemory( systemName );
391  SMBIOSFreeMemory( serviceTag );
392  SMBIOSFreeMemory( assetTag );
393  SMBIOSFreeMemory( biosVersion );
394  SMBIOSFreeMemory( vendorName );
395 
396  throw;
397  }
398 
399  SMBIOSFreeMemory( systemName );
400  SMBIOSFreeMemory( serviceTag );
401  SMBIOSFreeMemory( assetTag );
402  SMBIOSFreeMemory( biosVersion );
403  SMBIOSFreeMemory( vendorName );
404 
405  STD_TEST_END("");
406 }
407 
408 
409 // testInput.xml tests
410 string testPlatform::getTestInputString( string toFind, string section )
411 {
412  if (!doc)
413  throw skip_test();
414 
415  string foundString = "";
416 
417  try
418  {
420  XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *sysName = xmlutils::findElement( systeminfo, toFind, "", "" );
421  foundString = xmlutils::getNodeText( sysName );
422  }
423  catch( const exception & )
424  {
425  throw skip_test();
426  }
427 
428  return foundString;
429 }
430 
431 
432 void
434 {
435  STD_TEST_START_CHECKSKIP(getTestName().c_str() << " ");
436 
437  int systemId = SMBIOSGetDellSystemId ();
438 
439  string idStr = getTestInputString("idByte");
440  int id = strtol( idStr.c_str(), 0, 0);
441 
442  CPPUNIT_ASSERT_EQUAL ( id, systemId );
443 
444  STD_TEST_END("");
445 }
446 
447 string safeConvertToString( const char *str )
448 {
449  string fromSystem = "";
450  if( 0 != str )
451  {
452  fromSystem = str;
453  }
454  SMBIOSFreeMemory(str);
455  return fromSystem;
456 }
457 
458 void
460 {
461  STD_TEST_START_CHECKSKIP(getTestName().c_str() << " ");
462 
463  string fromSystem = safeConvertToString( SMBIOSGetSystemName() );
464  string testInput = getTestInputString( "systemName" );
465 
466  CPPUNIT_ASSERT_EQUAL ( testInput, fromSystem );
467  STD_TEST_END("");
468 }
469 
470 void
472 {
473  STD_TEST_START_CHECKSKIP(getTestName().c_str() << " ");
474 
475  string fromSystem = safeConvertToString( SMBIOSGetServiceTag() );
476  string testInput = getTestInputString( "serviceTag" );
477 
478  CPPUNIT_ASSERT_EQUAL ( testInput, fromSystem );
479 
480  STD_TEST_END("");
481 }
482 
483 // not part of public API, so just wing it here so that we can do the unit test.
484 extern char *getServiceTagFromCMOSToken();
485 
486 void
488 {
489  STD_TEST_START_CHECKSKIP(getTestName().c_str() << " ");
490 
491  string fromSystem = safeConvertToString( SMBIOSGetServiceTag() );
492  string testInput = getTestInputString( "serviceTag" );
493 
494  CPPUNIT_ASSERT_EQUAL ( testInput, fromSystem );
495 
496  string rawCMOSOrig("");
497  try
498  {
500  }
501  catch(const exception &)
502  {
503  // if service tag is not in SMBIOS, we cannot do the
504  // tests below
505  throw skip_test();
506  }
507 
508  CPPUNIT_ASSERT_EQUAL ( testInput, rawCMOSOrig );
509 
510  string tagToSet, shouldBe, rawCMOSNew;
511 
512  // test std 5-char svc tag
513  tagToSet = shouldBe = "NEWTG";
514  SMBIOSSetServiceTag("", tagToSet.c_str(), strlen(tagToSet.c_str()));
516  CPPUNIT_ASSERT_EQUAL ( shouldBe, rawCMOSNew );
517 
518  // test std 7-char svc tag (alphabet 1/3)
519  tagToSet = shouldBe = "BCDFGHJ";
520  SMBIOSSetServiceTag("", tagToSet.c_str(), strlen(tagToSet.c_str()));
522  CPPUNIT_ASSERT_EQUAL ( shouldBe, rawCMOSNew );
523 
524  // test std 7-char svc tag (alphabet 2/3)
525  tagToSet = shouldBe = "KLMNPQR";
526  SMBIOSSetServiceTag("", tagToSet.c_str(), strlen(tagToSet.c_str()));
528  CPPUNIT_ASSERT_EQUAL ( shouldBe, rawCMOSNew );
529 
530  // test std 7-char svc tag (alphabet 3/3)
531  tagToSet = shouldBe = "STVWXYZ";
532  SMBIOSSetServiceTag("", tagToSet.c_str(), strlen(tagToSet.c_str()));
534  CPPUNIT_ASSERT_EQUAL ( shouldBe, rawCMOSNew );
535 
536  // odd size (1)
537  tagToSet = shouldBe = "A";
538  SMBIOSSetServiceTag("", tagToSet.c_str(), strlen(tagToSet.c_str()));
540  CPPUNIT_ASSERT_EQUAL ( shouldBe, rawCMOSNew );
541 
542  // odd size (2)
543  tagToSet = shouldBe = "AB";
544  SMBIOSSetServiceTag("", tagToSet.c_str(), strlen(tagToSet.c_str()));
546  CPPUNIT_ASSERT_EQUAL ( shouldBe, rawCMOSNew );
547 
548  // odd size (3)
549  tagToSet = shouldBe = "ABC";
550  SMBIOSSetServiceTag("", tagToSet.c_str(), strlen(tagToSet.c_str()));
552  CPPUNIT_ASSERT_EQUAL ( shouldBe, rawCMOSNew );
553 
554  // odd size (4)
555  tagToSet = shouldBe = "ABCD";
556  SMBIOSSetServiceTag("", tagToSet.c_str(), strlen(tagToSet.c_str()));
558  CPPUNIT_ASSERT_EQUAL ( shouldBe, rawCMOSNew );
559 
560  // odd size (6)
561  tagToSet = "12DFGH";
562  shouldBe = "12DFGH0"; // invalid/missing chars for 7-char svc tag
563  // converted to '0'
564  SMBIOSSetServiceTag("", tagToSet.c_str(), strlen(tagToSet.c_str()));
566  CPPUNIT_ASSERT_EQUAL ( shouldBe, rawCMOSNew );
567 
568  // odd size (7)
569  tagToSet = shouldBe = "XGYZYYY";
570  SMBIOSSetServiceTag("", tagToSet.c_str(), strlen(tagToSet.c_str()));
572  CPPUNIT_ASSERT_EQUAL ( shouldBe, rawCMOSNew );
573 
574  // odd size (8)
575  tagToSet = "MNPQMNPQ";
576  shouldBe = "MNPQMNP"; // extra chars ignored
577  SMBIOSSetServiceTag("", tagToSet.c_str(), strlen(tagToSet.c_str()));
579  CPPUNIT_ASSERT_EQUAL ( shouldBe, rawCMOSNew );
580 
581  // invalid chars in 7-char tag
582  tagToSet = "ABEIOUD";
583  shouldBe = "AB0000D"; // invalid chars turned into '0';
584  SMBIOSSetServiceTag("", tagToSet.c_str(), strlen(tagToSet.c_str()));
586  CPPUNIT_ASSERT_EQUAL ( shouldBe, rawCMOSNew );
587 
588 
589  STD_TEST_END("");
590 }
591 
592 // not part of public API
593 extern char *getAssetTagFromToken();
594 
595 void
597 {
598  STD_TEST_START_CHECKSKIP(getTestName().c_str() << " ");
599 
600  string fromSystem = safeConvertToString( SMBIOSGetAssetTag() );
601  string testInput = getTestInputString( "assetTag" );
602  CPPUNIT_ASSERT_EQUAL ( testInput, fromSystem );
603 
604  string tagToSet = "1234567890";
605  SMBIOSSetAssetTag("", tagToSet.c_str(), strlen(tagToSet.c_str()));
606 
607  try
608  {
609  // only do this part of the test if system has CMOS tag
610  // This will throw exception if not present
611  fromSystem = safeConvertToString( getAssetTagFromToken() );
612  CPPUNIT_ASSERT_EQUAL ( tagToSet, fromSystem );
613  }
614  catch (const exception &)
615  {
616  }
617 
618  STD_TEST_END("");
619 }
620 
621 void
623 {
624  STD_TEST_START_CHECKSKIP(getTestName().c_str() << " ");
625 
626  string fromSystem = safeConvertToString( SMBIOSGetBiosVersion() );
627  string testInput = getTestInputString( "biosVersion" );
628 
629  CPPUNIT_ASSERT_EQUAL ( testInput, fromSystem );
630 
631  STD_TEST_END("");
632 }
633 
634 void
636 {
637  STD_TEST_START_CHECKSKIP(getTestName().c_str() << " ");
638 
639  int isDell = SMBIOSIsDellSystem ();
640 
641  string strval = getTestInputString( "isDellSystem" );
642  int isDellExpected = strtol( strval.c_str(), 0, 0);
643 
644  CPPUNIT_ASSERT_EQUAL ( isDell, isDellExpected );
645 
646  STD_TEST_END("");
647 }
648 
650 {
651  STD_TEST_START_CHECKSKIP(getTestName().c_str() << " ");
652 
653  // table should not be deleted when we are finished. It is managed by the
654  // factory. Factory will delete it for us when ->reset() is called.
655  const smbios::ISmbiosTable *table =
657 
659 
660  string vendorStr="";
661  string versionStr="";
662  string releaseStr="";
663 
664  if (!doc)
665  throw skip_test();
666 
667  // pull info out of xml
668  try
669  {
671  XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *biosInfo = xmlutils::findElement( smbios, "biosInformation", "", "" );
672  XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *vendor = xmlutils::findElement( biosInfo, "vendor", "", "" );
673  XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *version = xmlutils::findElement( biosInfo, "version", "", "" );
674  XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *release = xmlutils::findElement( biosInfo, "release", "", "" );
675  vendorStr = xmlutils::getNodeText( vendor );
676  versionStr = xmlutils::getNodeText( version );
677  releaseStr = xmlutils::getNodeText( release );
678 
679  }
680  catch( const exception & )
681  {
682  throw skip_test();
683  }
684 
685  const string string1( getString_FromItem(*item, 4) ); // BIOS VENDOR
686  const string string2( getString_FromItem(*item, 5) ); // BIOS VERSION
687  const string string3( getString_FromItem(*item, 8) ); // RELEASE DATE
688 
689  const string string4( item->getStringByStringNumber(1) ); //BIOS VENDOR
690  const string string5( item->getStringByStringNumber(2) ); //BIOS VERSION
691  const string string6( item->getStringByStringNumber(3) ); //RELEASE DATE
692 
693  CPPUNIT_ASSERT_EQUAL( vendorStr, string1 );
694  CPPUNIT_ASSERT_EQUAL( versionStr, string2 );
695  CPPUNIT_ASSERT_EQUAL( releaseStr, string3 );
696 
697  CPPUNIT_ASSERT_EQUAL( string1, string4 );
698  CPPUNIT_ASSERT_EQUAL( string2, string5 );
699  CPPUNIT_ASSERT_EQUAL( string3, string6 );
700 
701  STD_TEST_END("");
702 }
703 
704 void
706 {
707  STD_TEST_START_CHECKSKIP(getTestName().c_str() << " ");
708 
709  if( ! SMBIOSHasNvramStateBytes() )
710  throw skip_test();
711 
712  int testValue = 0;
713  SMBIOSGetNvramStateBytes( 0x0000 );
714 
715  // test DSA mode
716  testValue = 0x1234;
717  SMBIOSSetNvramStateBytes( testValue, 0x0000 );
718  CPPUNIT_ASSERT_EQUAL( testValue, SMBIOSGetNvramStateBytes( 0x0000 ) ); // DSA sees real value
719  CPPUNIT_ASSERT_EQUAL( 0x0000, SMBIOSGetNvramStateBytes( 0x8000 ) ); // toolkit should see 0
720  CPPUNIT_ASSERT_EQUAL( 0x0000, SMBIOSGetNvramStateBytes( 0xF100 ) ); // other should see 0
721 
722  // test DSA mode (proper mask off)
723  testValue = 0x9234; // we should not be able to set topmost bit
724  SMBIOSSetNvramStateBytes( testValue, 0x0000 );
725  CPPUNIT_ASSERT_EQUAL( (testValue & ~0x8000), SMBIOSGetNvramStateBytes( 0x0000 ) ); // DSA sees real value
726  CPPUNIT_ASSERT_EQUAL( 0x0000, SMBIOSGetNvramStateBytes( 0x8000 ) ); // toolkit should see 0
727  CPPUNIT_ASSERT_EQUAL( 0x0000, SMBIOSGetNvramStateBytes( 0xF100 ) ); // other should see 0
728 
729  // test Toolkit mode
730  testValue = 0x0234; // we should not be able to set topmost bit
731  SMBIOSSetNvramStateBytes( testValue, 0x8000 );
732  CPPUNIT_ASSERT_EQUAL( testValue, SMBIOSGetNvramStateBytes( 0x8000 ) ); //toolkit sees real value
733  CPPUNIT_ASSERT_EQUAL( 0x0000, SMBIOSGetNvramStateBytes( 0x0000 ) ); // DSA should see 0
734  CPPUNIT_ASSERT_EQUAL( 0x0000, SMBIOSGetNvramStateBytes( 0xF100 ) ); // other should see 0
735 
736  // test Toolkit mode (proper mask off)
737  testValue = 0x7234; // we should not be able to set topmost nibble (4 bits)
738  SMBIOSSetNvramStateBytes( testValue, 0x8000 );
739  CPPUNIT_ASSERT_EQUAL( (testValue & ~0xF000), SMBIOSGetNvramStateBytes( 0x8000 ) ); //toolkit sees real value
740  CPPUNIT_ASSERT_EQUAL( 0x0000, SMBIOSGetNvramStateBytes( 0x0000 ) ); // DSA should see 0
741  CPPUNIT_ASSERT_EQUAL( 0x0000, SMBIOSGetNvramStateBytes( 0xF100 ) ); // other should see 0
742 
743  // test other mode
744  testValue = 0x0034; // we should not be able to set topmost byte
745  SMBIOSSetNvramStateBytes( testValue, 0xF100 );
746  CPPUNIT_ASSERT_EQUAL( testValue, SMBIOSGetNvramStateBytes( 0xF100 ) ); // other sees real value
747  CPPUNIT_ASSERT_EQUAL( 0x0000, SMBIOSGetNvramStateBytes( 0x0000 ) ); // DSA should see 0
748  CPPUNIT_ASSERT_EQUAL( 0x0000, SMBIOSGetNvramStateBytes( 0x8000 ) ); // DSA should see 0
749 
750  // test other mode (proper mask off)
751  testValue = 0x7234; // we should not be able to set topmost byte
752  SMBIOSSetNvramStateBytes( testValue, 0xF100 );
753  CPPUNIT_ASSERT_EQUAL( (testValue & ~0xFF00), SMBIOSGetNvramStateBytes( 0xF100 ) ); // other sees real value
754  CPPUNIT_ASSERT_EQUAL( 0x0000, SMBIOSGetNvramStateBytes( 0x0000 ) ); // DSA should see 0
755  CPPUNIT_ASSERT_EQUAL( 0x0000, SMBIOSGetNvramStateBytes( 0x8000 ) ); // DSA should see 0
756 
757  STD_TEST_END("");
758 }
759 
760 void
762 {
763  STD_TEST_START_CHECKSKIP(getTestName().c_str() << " ");
764 
765  if( ! SMBIOSHasBootToUp() )
766  throw skip_test();
767 
769  CPPUNIT_ASSERT_EQUAL( 1, SMBIOSGetBootToUp() );
770 
772  CPPUNIT_ASSERT_EQUAL( 0, SMBIOSGetBootToUp() );
773 
775  CPPUNIT_ASSERT_EQUAL( 1, SMBIOSGetBootToUp() );
776 
778  CPPUNIT_ASSERT_EQUAL( 0, SMBIOSGetBootToUp() );
779 
780  STD_TEST_END("");
781 }
782 
783 
784 void
786 {
787  STD_TEST_START_CHECKSKIP(getTestName().c_str() << " ");
788 
789  const smbios::ISmbiosTable *table =
791 
793 
794  // access string '0' should always throw. (string offset start at 1, per
795  // spec)
796  ASSERT_THROWS( item->getStringByStringNumber(0), smbios::StringUnavailable );
797 
798  if (!doc)
799  throw skip_test();
800 
801  int numStrings = 0;
802  // pull info out of xml
803  try
804  {
806  XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *biosInfo = xmlutils::findElement( smbios, "biosInformation", "", "" );
807  numStrings = strtoul( xmlutils::safeGetAttribute( biosInfo, "numstrings" ).c_str(), 0, 0 );
808  }
809  catch( const exception & )
810  {
811  throw skip_test();
812  }
813 
814  // Should not throw (cast to void to eliminate unused var warn)
815  if( numStrings > 0 )
816  (void) (item->getStringByStringNumber(numStrings));
817 
818  ASSERT_THROWS( item->getStringByStringNumber(numStrings + 1), smbios::StringUnavailable );
819  ASSERT_THROWS( item->getStringByStringNumber(numStrings + 2), smbios::StringUnavailable );
820 
821  STD_TEST_END("");
822 }
823 
824 
825 void
827 {
828  STD_TEST_START_CHECKSKIP(getTestName().c_str() << " ");
829 
830  if (!doc)
831  throw skip_test();
832 
833  u32 offset = 0;
834  try
835  {
837  offset = strtoul( xmlutils::safeGetAttribute( smbios, "offset" ).c_str(), 0, 0 );
838  if( 0 == offset )
839  {
840  throw skip_test();
841  }
842  }
843  catch( const exception & )
844  {
845  throw skip_test();
846  }
847 
848  smbios::SmbiosFactory::getFactory()->setParameter("offset", offset);
849  const smbios::ISmbiosTable *table =
851 
852  int tableEntriesCounted = 0;
854  while( item != table->end() )
855  {
856  tableEntriesCounted++;
857  (void) *item; // do this to sniff out possible errors with deref iterator.
858  ++item;
859  }
860 
861  CPPUNIT_ASSERT( tableEntriesCounted == table->getNumberOfEntries() );
862  STD_TEST_END("");
863 }
864 
865 void
867 {
868  STD_TEST_START_CHECKSKIP(getTestName().c_str() << " ");
869 
870  if (!doc)
871  throw skip_test();
872 
873  u32 offset = 0;
874  try
875  {
877  offset = strtoul( xmlutils::safeGetAttribute( smbios, "offset" ).c_str(), 0, 0 );
878  if( 0 == offset )
879  {
880  throw skip_test();
881  }
882  }
883  catch( const exception & )
884  {
885  throw skip_test();
886  }
887 
888  //
889  // TEST BAD FILENAMES
890  // construct our table with various invalid file names
891  //
893 
894  // use auto_ptr so in case it does _not_ throw, we don't leak mem in the test.
895  // DO NOT USE ->getSingleton() here... we use ->makeNew() on purpose.
896  // This is an internal test and the parameters of this test mean we should _not_ use a singleton.
897  factory->setParameter("offset", 1);
898  ASSERT_THROWS( auto_ptr<const smbios::ISmbiosTable>p(factory->makeNew()), smbios::IException );
899 
900  factory->setParameter("offset", 1000);
901  ASSERT_THROWS( auto_ptr<const smbios::ISmbiosTable>p(factory->makeNew()), smbios::IException );
902 
903  factory->setParameter("offset", 0xFFFFFUL ); // F_BLOCK_END (private definition)
904  ASSERT_THROWS( auto_ptr<const smbios::ISmbiosTable>p(factory->makeNew()), smbios::IException );
905 
906  factory->setParameter("offset", 0xFFFFFUL - 1); // F_BLOCK_END (private definition)
907  ASSERT_THROWS( auto_ptr<const smbios::ISmbiosTable>p(factory->makeNew()), smbios::IException );
908 
909  smbios::SmbiosFactory::getFactory()->setParameter("offset", offset + 1);
910  ASSERT_THROWS( auto_ptr<const smbios::ISmbiosTable> table( factory->makeNew() ), smbios::IException );
911 
912  smbios::SmbiosFactory::getFactory()->setParameter("offset", offset - 1);
913  ASSERT_THROWS( auto_ptr<const smbios::ISmbiosTable> table( factory->makeNew() ), smbios::IException );
914 
915  // should not be able to use no-argument constructor...
916  // UNCOMMENT TO CHECK.
917  // THIS TEST DOES NOT COMPILE. IT SHOULD NOT COMPILE
918  // DUE TO THE DEFINITION OF SmbiosTable.
919  //ASSERT_THROWS( smbios::SmbiosTableFileIo myTable1, smbios::PermissionException);
920 
921  STD_TEST_END("");
922 }
923 
924