From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM02-SN1-obe.outbound.protection.outlook.com (NAM02-SN1-obe.outbound.protection.outlook.com [40.107.77.112]) by mx.groups.io with SMTP id smtpd.web12.710.1581054201269110799 for ; Thu, 06 Feb 2020 21:43:21 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@microsoft.com header.s=selector2 header.b=OE7/gMH/; spf=pass (domain: microsoft.com, ip: 40.107.77.112, mailfrom: bret.barkelew@microsoft.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=mZDFxLH3Uu9Z13nGTwDNBZL5RvCb4MwQuayp8BdJJSb9ZZBnd2XgfwzNJO8WvHU4i7JfuOvrFlhiRV1NcnZ1OnEJMomDgNBSTmYuGW0K0V7XgxPMVBdBrprPL4XPNifSqfaJybqrsCxxwkphR50i/4jqEbcNdpe444tnfTPPvBzA/SeVPVcGK+tkzXq0i4X5aYuihCEJQyt+v2kYlgJuNL79HsLhybteQNABZUMJWf1I5yZ7IYWvdrX8p6dofKNaCK9R+W7vY/HBl49frAG55CTqVTqV3kyDcxctTGjEZMsyuAut6na3q7EjuXZEzX5obVxOmoE5lwL84Tw5lo/M5Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=DQcKLgib5TWvipcEw4AbuKAba2NpSu7q7FAqZ9b1vzg=; b=IVjX0lbLgTz1olsGfpqEfcXTTVJHW/gHHpOlJW5/nCpvkXYpgMca2hEXxF16isO9RwDb0G/0wjwkFxDq6U5dJvXKTug3UnMKinWpJbLsu8dRRdbS397Nkl2s8qkZItPXwSfAeNY9i9Pi74ubDfsRrt7ow039+cG3qGhVXH6uR4r3GB+S3QbPj5vBRatFOeKh2aOH60aE92prgldLSiFuHUDKQ7eTQ2yxSg4AMCCnw5JPjo9O/bbtx8bNXt6y5JvatfLbzq3LI3DekEQfDkhPxzA92RZBI+7tbn/AWogeil6AlzSHmP60cFDSXnZR061pyV4W/SOX0V+BQWGJgx57tg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=microsoft.com; dmarc=pass action=none header.from=microsoft.com; dkim=pass header.d=microsoft.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=DQcKLgib5TWvipcEw4AbuKAba2NpSu7q7FAqZ9b1vzg=; b=OE7/gMH/h2ke5j0fTtgLrD/34mKmD7KaMNzzF8CYq+4m+1LhxqOFxpvJECaw6x6TJEXjLbLhcP2ALizGCs3SQJxmi/PzkL5er+1AGlgusizeiFv2DcFsnS+TvMWnM8aHXypnctk5zvpg71OM6iQz8h7pGi1qjwhOtZENlpFRW0k= Received: from CY4PR21MB0743.namprd21.prod.outlook.com (10.173.189.9) by CY4PR21MB0775.namprd21.prod.outlook.com (10.173.192.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2729.6; Fri, 7 Feb 2020 05:43:19 +0000 Received: from CY4PR21MB0743.namprd21.prod.outlook.com ([fe80::b13b:1c6b:befc:583c]) by CY4PR21MB0743.namprd21.prod.outlook.com ([fe80::b13b:1c6b:befc:583c%7]) with mapi id 15.20.2729.010; Fri, 7 Feb 2020 05:43:19 +0000 From: "Bret Barkelew" To: "Wu, Hao A" , "devel@edk2.groups.io" , "Kinney, Michael D" , Sean Brogan CC: Sean Brogan , "Gao, Liming" Subject: Re: [edk2-devel] [Patch 03/11] MdePkg/Include/Library: Add UnitTestLib class Thread-Topic: [edk2-devel] [Patch 03/11] MdePkg/Include/Library: Add UnitTestLib class Thread-Index: AQHV3VUQk5tPB/gojkyUV5D925nx3KgPOEYu Date: Fri, 7 Feb 2020 05:43:18 +0000 Message-ID: References: <20200124021032.13808-1-michael.d.kinney@intel.com> <20200124021032.13808-4-michael.d.kinney@intel.com>, In-Reply-To: Accept-Language: en-US X-Mentions: sean.brogan@microsoft.com X-MS-Has-Attach: X-MS-TNEF-Correlator: msip_labels: MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Enabled=True;MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_SiteId=72f988bf-86f1-41af-91ab-2d7cd011db47;MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_SetDate=2020-02-07T05:43:05.4958115Z;MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_ContentBits=0;MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Method=Privileged authentication-results: spf=none (sender IP is ) smtp.mailfrom=Bret.Barkelew@microsoft.com; x-originating-ip: [174.21.64.62] x-ms-publictraffictype: Email x-ms-office365-filtering-ht: Tenant x-ms-office365-filtering-correlation-id: 785d4fce-e7b6-44e6-0df6-08d7ab90a2c0 x-ms-traffictypediagnostic: CY4PR21MB0775:|CY4PR21MB0775:|CY4PR21MB0775: x-ms-exchange-transport-forked: True x-ld-processed: 72f988bf-86f1-41af-91ab-2d7cd011db47,ExtAddr x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:357; x-forefront-prvs: 0306EE2ED4 x-forefront-antispam-report: SFV:NSPM;SFS:(10019020)(4636009)(396003)(39860400002)(346002)(376002)(136003)(366004)(189003)(199004)(6636002)(76116006)(66446008)(64756008)(66556008)(66476007)(110136005)(54906003)(52536014)(66946007)(5660300002)(7696005)(91956017)(2906002)(10290500003)(33656002)(316002)(86362001)(71200400001)(6506007)(8936002)(186003)(966005)(8676002)(81156014)(55016002)(53546011)(8990500004)(4326008)(81166006)(30864003)(478600001)(26005)(9686003)(559001)(579004);DIR:OUT;SFP:1102;SCL:1;SRVR:CY4PR21MB0775;H:CY4PR21MB0743.namprd21.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; received-spf: None (protection.outlook.com: microsoft.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: K0Z4lh0GNvr/Kk33obpFe3RWWamyWjdqHsgO6VeB5HrTZn6S/lYxMxXuBcdwOHlckWrPKDZDrKrnpYxBgl7X7yqynITJtzq8OyZAElSkTXpUGb9m3vReJ71pwnCwBb3jodtKzn3oeEY7F8NfmEeQF1EvLhrOm34R8f3651fwtymSfCskGVIIGOlsCoy+l4drf2vViyB1lcQvNxY7y8lkyz5dVMrPmV2FzV6Ja3HUgqaYUneJaqrlA2G1PXmCI5VSIycfvMnoSBfQEzZKbt4FacWmEox46GCChOwn7IH/CN7hXOa3u4Vdh2tUfswox+y+trgv8gOg8M8cwBon5m6hVMe13JlE7vUuEbCsv5ldY9V3LK3dSF2H7wXTMpXYceidT+q0x+L0JPDjbc96+FZf8iwE/EgQtMBx/MJyY+SkfxUN9oQ+exVezqLqbCpaWmrqYMUKjXoWy8Dkvi7soF7iqno8AY5bquYe3tm21ISFH0x+RHduuGM1mPT+IXYblKs805MJ3QEf3EF9oTkK/L+KwQ== x-ms-exchange-antispam-messagedata: 5ThAJM1jJC92x3i/RH369T8ErHv3dhTqXMogloKlFXZdfbn5Eyn+3p7Hem337X3rox2Sz3nwVeEH2A0Wi8+LB+pjxrbW3KneyMr+6kc0BPlVDV21NRM2Cl7kLk9nezt2si6E14TXv5tQgRyHrXGf+w== MIME-Version: 1.0 X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-Network-Message-Id: 785d4fce-e7b6-44e6-0df6-08d7ab90a2c0 X-MS-Exchange-CrossTenant-originalarrivaltime: 07 Feb 2020 05:43:18.9030 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: S/wk6RC4uyKNUi4OrDH1NQ5sulrrJ/9zVEhZlkF3cPOdiTKX2EjsaI6JL3tzsqUAvJsbV92WQO2tuxwfJ1j0NA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR21MB0775 Content-Language: en-US Content-Type: multipart/alternative; boundary="_000_CY4PR21MB0743F68EE69A56DD7F0C6F5FEF1C0CY4PR21MB0743namp_" --_000_CY4PR21MB0743F68EE69A56DD7F0C6F5FEF1C0CY4PR21MB0743namp_ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable @Sean, how would these have been missed b= y the spell checker? - Bret ________________________________ From: Wu, Hao A Sent: Thursday, February 6, 2020 5:22:21 PM To: devel@edk2.groups.io ; Kinney, Michael D Cc: Bret Barkelew ; Sean Brogan ; Bret Barkelew ; Gao, Liming Subject: [EXTERNAL] RE: [edk2-devel] [Patch 03/11] MdePkg/Include/Library:= Add UnitTestLib class A couple of typos (some of them occur multiple times) in UnitTestLib.h: Funtions -> Functions paramter -> parameter Null-terminaled -> Null-terminated dispached -> dispatched storage devide -> storage device With them addressed, Reviewed-by: Hao A Wu Best Regards, Hao Wu > -----Original Message----- > From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of > Michael D Kinney > Sent: Friday, January 24, 2020 10:10 AM > To: devel@edk2.groups.io > Cc: Bret Barkelew; Sean Brogan; Bret Barkelew; Gao, Liming > Subject: [edk2-devel] [Patch 03/11] MdePkg/Include/Library: Add UnitTest= Lib > class > > From: Bret Barkelew > > Add UnitTestLib class to MdePkg that provides services > and macros to implement unit tests. These services and > macros support the following features: > > * Create a Unit Test Framework > * Add a Unit Test Suite to a Unit Test Framework > + Support optional step that executes before a Unit > Test Suite is started. > + Support optional step that executes after a Unit > Test Suite is finished. > * Add a Unit Test to a Unit Test Suite > + Support optional step that executes before a Unit > Test is started. > + Support optional step that executes after a Unit > Test is finished. > * Run all unit tests added to a Unit Test Framework > * Save Unit Test Framework state to persistent storage > * Support assertion checks in a unit test for TRUE, FALSE, > EQUAL, MEM_EQUAL, NOT_EFI_ERROR, STATUS_EQUAL, and NOT_NULL. > * Support generation of log messages at ERROR, WARN, INFO, > and VERBOSE levels. > > Cc: Sean Brogan > Cc: Bret Barkelew > Cc: Liming Gao > Signed-off-by: Michael D Kinney > --- > MdePkg/Include/Library/UnitTestLib.h | 757 > +++++++++++++++++++++++++++ > MdePkg/MdePkg.dec | 4 + > 2 files changed, 761 insertions(+) > create mode 100644 MdePkg/Include/Library/UnitTestLib.h > > diff --git a/MdePkg/Include/Library/UnitTestLib.h > b/MdePkg/Include/Library/UnitTestLib.h > new file mode 100644 > index 0000000000..757ebaf6ba > --- /dev/null > +++ b/MdePkg/Include/Library/UnitTestLib.h > @@ -0,0 +1,757 @@ > +/** @file > + Provides a unit test framework. This allows tests to focus on testin= g logic > + and the framework to focus on runnings, reporting, statistics, etc. > + > + Copyright (c) Microsoft Corporation.
> + Copyright (c) 2020, Intel Corporation. All rights reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef __UNIT_TEST_LIB_H__ > +#define __UNIT_TEST_LIB_H__ > + > +/// > +/// Unit Test Status > +/// > +typedef UINT32 UNIT_TEST_STATUS; > +#define UNIT_TEST_PASSED (0) > +#define UNIT_TEST_ERROR_PREREQUISITE_NOT_MET (1) > +#define UNIT_TEST_ERROR_TEST_FAILED (2) > +#define UNIT_TEST_ERROR_CLEANUP_FAILED (3) > +#define UNIT_TEST_SKIPPED (0xFFFFFFFD) > +#define UNIT_TEST_RUNNING (0xFFFFFFFE) > +#define UNIT_TEST_PENDING (0xFFFFFFFF) > + > +/// > +/// Declare PcdUnitTestLogLevel bits and UnitTestLog() ErrorLevel > parameter. > +/// > +#define UNIT_TEST_LOG_LEVEL_ERROR BIT0 > +#define UNIT_TEST_LOG_LEVEL_WARN BIT1 > +#define UNIT_TEST_LOG_LEVEL_INFO BIT2 > +#define UNIT_TEST_LOG_LEVEL_VERBOSE BIT3 > + > +/// > +/// Unit Test Framework Handle > +/// > +struct UNIT_TEST_FRAMEWORK_OBJECT; > +typedef struct UNIT_TEST_FRAMEWORK_OBJECT > *UNIT_TEST_FRAMEWORK_HANDLE; > + > +/// > +/// Unit Test Suite Handle > +/// > +struct UNIT_TEST_SUITE_OBJECT; > +typedef struct UNIT_TEST_SUITE_OBJECT *UNIT_TEST_SUITE_HANDLE; > + > +/// > +/// Unit Test Handle > +/// > +struct UNIT_TEST_OBJECT; > +typedef struct UNIT_TEST_OBJECT *UNIT_TEST_HANDLE; > + > +/// > +/// Unit Test Context > +/// > +typedef VOID* UNIT_TEST_CONTEXT; > + > +/** > + The prototype for a single UnitTest case function. > + > + Funtions with this prototype are registered to be dispatched by the > + UnitTest framework, and results are recorded as test Pass or Fail. > + > + @param[in] Context [Optional] An optional paramter that enables: > + 1) test-case reuse with varied parameters and > + 2) test-case re-entry for Target tests that ne= ed a > + reboot. This parameter is a VOID* and it is t= he > + responsibility of the test author to ensure th= at the > + contents are well understood by all test cases= that may > + consume it. > + > + @retval UNIT_TEST_PASSED The Unit test has completed and= the > test > + case was successful. > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has faile= d. > + > +**/ > +typedef > +UNIT_TEST_STATUS > +(EFIAPI *UNIT_TEST_FUNCTION)( > + IN UNIT_TEST_CONTEXT Context > + ); > + > +/** > + Unit-Test Prerequisite Function pointer type. > + > + Funtions with this prototype are registered to be dispatched by the u= nit > test > + framework prior to a given test case. If this prereq function returns > + UNIT_TEST_ERROR_PREREQUISITE_NOT_MET, the test case will be > skipped. > + > + @param[in] Context [Optional] An optional paramter that enables: > + 1) test-case reuse with varied parameters and > + 2) test-case re-entry for Target tests that ne= ed a > + reboot. This parameter is a VOID* and it is t= he > + responsibility of the test author to ensure th= at the > + contents are well understood by all test cases= that may > + consume it. > + > + @retval UNIT_TEST_PASSED Unit test case prerequ= isites > + are met. > + @retval UNIT_TEST_ERROR_PREREQUISITE_NOT_MET Test case should > be skipped. > + > +**/ > +typedef > +UNIT_TEST_STATUS > +(EFIAPI *UNIT_TEST_PREREQUISITE)( > + IN UNIT_TEST_CONTEXT Context > + ); > + > +/** > + Unit-Test Cleanup (after) function pointer type. > + > + Funtions with this prototype are registered to be dispatched by the > + unit test framework after a given test case. This will be called even= if the > + test case returns an error, but not if the prerequisite fails and the= test is > + skipped. The purpose of this function is to clean up any global stat= e or > + test data. > + > + @param[in] Context [Optional] An optional paramter that enables: > + 1) test-case reuse with varied parameters and > + 2) test-case re-entry for Target tests that ne= ed a > + reboot. This parameter is a VOID* and it is t= he > + responsibility of the test author to ensure th= at the > + contents are well understood by all test cases= that may > + consume it. > + > + @retval UNIT_TEST_PASSED Test case cleanup succeeded. > + @retval UNIT_TEST_ERROR_CLEANUP_FAILED Test case cleanup failed. > + > +**/ > +typedef > +VOID > +(EFIAPI *UNIT_TEST_CLEANUP)( > + IN UNIT_TEST_CONTEXT Context > + ); > + > +/** > + Unit-Test Test Suite Setup (before) function pointer type. Funtions w= ith this > + prototype are registered to be dispatched by the UnitTest framework p= rior > to > + running any of the test cases in a test suite. It will only be run o= nce at > + the beginning of the suite (not prior to each case). > + > + The purpose of this function is to set up any global state or test da= ta. > +**/ > +typedef > +VOID > +(EFIAPI *UNIT_TEST_SUITE_SETUP)( > + VOID > + ); > + > +/** > + Unit-Test Test Suite Teardown (after) function pointer type. Funtion= s with > + this prototype are registered to be dispatched by the UnitTest framew= ork > after > + running all of the test cases in a test suite. It will only be run o= nce at > + the end of the suite. > + > + The purpose of this function is to clean up any global state or test = data. > +**/ > +typedef > +VOID > +(EFIAPI *UNIT_TEST_SUITE_TEARDOWN)( > + VOID > + ); > + > +/** > + Method to Initialize the Unit Test framework. This function register= s the > + test name and also initializes the internal state of the test framewo= rk to > + receive any new suites and tests. > + > + @param[out] FrameworkHandle Unit test framework to be created. > + @param[in] Title Null-terminated ASCII string that is th= e user > + friendly name of the framework. String = is > + copied. > + @param[in] ShortTitle Null-terminaled ASCII short string that= is the > + short name of the framework with no spa= ces. > + String is copied. > + @param[in] VersionString Null-terminaled ASCII version string fo= r the > + framework. String is copied. > + > + @retval EFI_SUCCESS The unit test framework was initializ= ed. > + @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL. > + @retval EFI_INVALID_PARAMETER Title is NULL. > + @retval EFI_INVALID_PARAMETER ShortTitle is NULL. > + @retval EFI_INVALID_PARAMETER VersionString is NULL. > + @retval EFI_INVALID_PARAMETER ShortTitle is invalid. > + @retval EFI_OUT_OF_RESOURCES There are not enough resources > available to > + initialize the unit test framework. > +**/ > +EFI_STATUS > +EFIAPI > +InitUnitTestFramework ( > + OUT UNIT_TEST_FRAMEWORK_HANDLE *FrameworkHandle, > + IN CHAR8 *Title, > + IN CHAR8 *ShortTitle, > + IN CHAR8 *VersionString > + ); > + > +/** > + Registers a Unit Test Suite in the Unit Test Framework. > + At least one test suite must be registered, because all test cases mu= st be > + within a unit test suite. > + > + @param[out] SuiteHandle Unit test suite to create > + @param[in] FrameworkHandle Unit test framework to add unit test su= ite > to > + @param[in] Title Null-terminated ASCII string that is th= e user > + friendly name of the test suite. Strin= g is > + copied. > + @param[in] Name Null-terminated ASCII string that is th= e short > + name of the test suite with no spaces. = String > + is copied. > + @param[in] Setup Setup function, runs before suite. Thi= s is an > + optional parameter that may be NULL. > + @param[in] Teardown Teardown function, runs after suite. T= his is > an > + optional parameter that may be NULL. > + > + @retval EFI_SUCCESS The unit test suite was created. > + @retval EFI_INVALID_PARAMETER SuiteHandle is NULL. > + @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL. > + @retval EFI_INVALID_PARAMETER Title is NULL. > + @retval EFI_INVALID_PARAMETER Name is NULL. > + @retval EFI_OUT_OF_RESOURCES There are not enough resources > available to > + initialize the unit test suite. > +**/ > +EFI_STATUS > +EFIAPI > +CreateUnitTestSuite ( > + OUT UNIT_TEST_SUITE_HANDLE *SuiteHandle, > + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle, > + IN CHAR8 *Title, > + IN CHAR8 *Name, > + IN UNIT_TEST_SUITE_SETUP Setup OPTIONAL, > + IN UNIT_TEST_SUITE_TEARDOWN Teardown OPTIONAL > + ); > + > +/** > + Adds test case to Suite > + > + @param[in] SuiteHandle Unit test suite to add test to. > + @param[in] Description Null-terminated ASCII string that is the us= er > + friendly description of a test. String is = copied. > + @param[in] Name Null-terminated ASCII string that is the sh= ort > name > + of the test with no spaces. String is copi= ed. > + @param[in] Function Unit test function. > + @param[in] Prerequisite Prerequisite function, runs before test. T= his is > + an optional parameter that may be NULL. > + @param[in] CleanUp Clean up function, runs after test. This i= s an > + optional parameter that may be NULL. > + @param[in] Context Pointer to context. This is an optional > parameter > + that may be NULL. > + > + @retval EFI_SUCCESS The unit test case was added to Suite= . > + @retval EFI_INVALID_PARAMETER SuiteHandle is NULL. > + @retval EFI_INVALID_PARAMETER Description is NULL. > + @retval EFI_INVALID_PARAMETER Name is NULL. > + @retval EFI_INVALID_PARAMETER Function is NULL. > + @retval EFI_OUT_OF_RESOURCES There are not enough resources > available to > + add the unit test case to Suite. > +**/ > +EFI_STATUS > +EFIAPI > +AddTestCase ( > + IN UNIT_TEST_SUITE_HANDLE SuiteHandle, > + IN CHAR8 *Description, > + IN CHAR8 *Name, > + IN UNIT_TEST_FUNCTION Function, > + IN UNIT_TEST_PREREQUISITE Prerequisite OPTIONAL, > + IN UNIT_TEST_CLEANUP CleanUp OPTIONAL, > + IN UNIT_TEST_CONTEXT Context OPTIONAL > + ); > + > +/** > + Execute all unit test cases in all unit test suites added to a Framew= ork. > + > + Once a unit test framework is initialized and all unit test suites an= d unit > + test cases are registered, this function will cause the unit test fra= mework > to > + dispatch all unit test cases in sequence and record the results for r= eporting. > + > + @param[in] FrameworkHandle A handle to the current running > framework that > + dispatched the test. Necessary for reco= rding > + certain test events with the framework. > + > + @retval EFI_SUCCESS All test cases were dispached. > + @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL. > +**/ > +EFI_STATUS > +EFIAPI > +RunAllTestSuites ( > + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle > + ); > + > +/** > + Cleanup a test framework. > + > + After tests are run, this will teardown the entire framework and free= all > + allocated data within. > + > + @param[in] FrameworkHandle A handle to the current running > framework that > + dispatched the test. Necessary for reco= rding > + certain test events with the framework. > + > + @retval EFI_SUCCESS All resources associated with framewo= rk > were > + freed. > + @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL. > +**/ > +EFI_STATUS > +EFIAPI > +FreeUnitTestFramework ( > + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle > + ); > + > +/** > + Leverages a framework-specific mechanism (see UnitTestPersistenceLib = if > you're > + a framework author) to save the state of the executing framework alon= g > with > + any allocated data so that the test may be resumed upon reentry. A te= st > case > + should pass any needed context (which, to prevent an infinite loop, s= hould > be > + at least the current execution count) which will be saved by the fram= ework > and > + passed to the test case upon resume. > + > + Generally called from within a test case prior to quitting or rebooti= ng. > + > + @param[in] FrameworkHandle A handle to the current running > framework that > + dispatched the test. Necessary for re= cording > + certain test events with the framework= . > + @param[in] ContextToSave A buffer of test case-specific data to= be > saved > + along with framework state. Will be p= assed as > + "Context" to the test case upon resume= . This > + is an optional parameter that may be N= ULL. > + @param[in] ContextToSaveSize Size of the ContextToSave buffer. > + > + @retval EFI_SUCCESS The framework state and context were = saved. > + @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL. > + @retval EFI_INVALID_PARAMETER ContextToSave is not NULL and > + ContextToSaveSize is 0. > + @retval EFI_INVALID_PARAMETER ContextToSave is >=3D 4GB. > + @retval EFI_OUT_OF_RESOURCES There are not enough resources > available to > + save the framework and context state. > + @retval EFI_DEVICE_ERROR The framework and context state could > not be > + saved to a persistent storage devide = due to a > + device error. > +**/ > +EFI_STATUS > +EFIAPI > +SaveFrameworkState ( > + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle, > + IN UNIT_TEST_CONTEXT ContextToSave OPTIONAL, > + IN UINTN ContextToSaveSize > + ); > + > +/** > + This macro uses the framework assertion logic to check an expression = for > + "TRUE". If the expression evaluates to TRUE, execution continues. > + Otherwise, the test case immediately returns > UNIT_TEST_ERROR_TEST_FAILED. > + > + @param[in] Expression Expression to be evaluated for TRUE. > +**/ > +#define UT_ASSERT_TRUE(Expression) = \ > + if(!UnitTestAssertTrue ((Expression), __FUNCTION__, __LINE__, __FILE_= _, > #Expression)) { \ > + return UNIT_TEST_ERROR_TEST_FAILED; = \ > + } > + > +/** > + This macro uses the framework assertion logic to check an expression = for > + "FALSE". If the expression evaluates to FALSE, execution continues. > + Otherwise, the test case immediately returns > UNIT_TEST_ERROR_TEST_FAILED. > + > + @param[in] Expression Expression to be evaluated for FALSE. > +**/ > +#define UT_ASSERT_FALSE(Expression) = \ > + if(!UnitTestAssertFalse ((Expression), __FUNCTION__, __LINE__, __FILE= __, > #Expression)) { \ > + return UNIT_TEST_ERROR_TEST_FAILED; = \ > + } > + > +/** > + This macro uses the framework assertion logic to check whether two > simple > + values are equal. If the values are equal, execution continues. > + Otherwise, the test case immediately returns > UNIT_TEST_ERROR_TEST_FAILED. > + > + @param[in] ValueA Value to be compared for equality (64-bit > comparison). > + @param[in] ValueB Value to be compared for equality (64-bit > comparison). > +**/ > +#define UT_ASSERT_EQUAL(ValueA, ValueB) > \ > + if(!UnitTestAssertEqual ((UINT64)(ValueA), (UINT64)(ValueB), > __FUNCTION__, __LINE__, __FILE__, #ValueA, #ValueB)) { \ > + return UNIT_TEST_ERROR_TEST_FAILED; > \ > + } > + > +/** > + This macro uses the framework assertion logic to check whether two > memory > + buffers are equal. If the buffers are equal, execution continues. > + Otherwise, the test case immediately returns > UNIT_TEST_ERROR_TEST_FAILED. > + > + @param[in] BufferA Pointer to a buffer for comparison. > + @param[in] BufferB Pointer to a buffer for comparison. > + @param[in] Length Number of bytes to compare in BufferA and Buffer= B. > +**/ > +#define UT_ASSERT_MEM_EQUAL(BufferA, BufferB, Length) > \ > + if(!UnitTestAssertMemEqual ((VOID *)(UINTN)(BufferA), (VOID > *)(UINTN)(BufferB), (UINTN)Length, __FUNCTION__, __LINE__, __FILE__, > #BufferA, #BufferB)) { \ > + return UNIT_TEST_ERROR_TEST_FAILED; > \ > + } > + > +/** > + This macro uses the framework assertion logic to check whether two > simple > + values are non-equal. If the values are non-equal, execution continu= es. > + Otherwise, the test case immediately returns > UNIT_TEST_ERROR_TEST_FAILED. > + > + @param[in] ValueA Value to be compared for inequality (64-bit > comparison). > + @param[in] ValueB Value to be compared for inequality (64-bit > comparison). > +**/ > +#define UT_ASSERT_NOT_EQUAL(ValueA, ValueB) > \ > + if(!UnitTestAssertNotEqual ((UINT64)(ValueA), (UINT64)(ValueB), > __FUNCTION__, __LINE__, __FILE__, #ValueA, #ValueB)) { \ > + return UNIT_TEST_ERROR_TEST_FAILED; > \ > + } > + > +/** > + This macro uses the framework assertion logic to check whether an > EFI_STATUS > + value is !EFI_ERROR(). If the status is !EFI_ERROR(), execution cont= inues. > + Otherwise, the test case immediately returns > UNIT_TEST_ERROR_TEST_FAILED. > + > + @param[in] Status EFI_STATUS value to check. > +**/ > +#define UT_ASSERT_NOT_EFI_ERROR(Status) = \ > + if(!UnitTestAssertNotEfiError ((Status), __FUNCTION__, __LINE__, > __FILE__, #Status)) { \ > + return UNIT_TEST_ERROR_TEST_FAILED; = \ > + } > + > +/** > + This macro uses the framework assertion logic to check whether two > EFI_STATUS > + values are equal. If the values are equal, execution continues. > + Otherwise, the test case immediately returns > UNIT_TEST_ERROR_TEST_FAILED. > + > + @param[in] Status EFI_STATUS values to compare for equality. > + @param[in] Expected EFI_STATUS values to compare for equality. > +**/ > +#define UT_ASSERT_STATUS_EQUAL(Status, Expected) > \ > + if(!UnitTestAssertStatusEqual ((Status), (Expected), __FUNCTION__, > __LINE__, __FILE__, #Status)) { \ > + return UNIT_TEST_ERROR_TEST_FAILED; > \ > + } > + > +/** > + This macro uses the framework assertion logic to check whether a poin= ter > is > + not NULL. If the pointer is not NULL, execution continues. Otherwise= , the > + test case immediately returns UNIT_TEST_ERROR_TEST_FAILED. > + > + @param[in] Pointer Pointer to be checked against NULL. > +**/ > +#define UT_ASSERT_NOT_NULL(Pointer) = \ > + if(!UnitTestAssertNotNull ((Pointer), __FUNCTION__, __LINE__, __FILE_= _, > #Pointer)) { \ > + return UNIT_TEST_ERROR_TEST_FAILED; = \ > + } > + > +/** > + If Expression is TRUE, then TRUE is returned. > + If Expression is FALSE, then an assert is triggered and the location = of the > + assert provided by FunctionName, LineNumber, FileName, and Descriptio= n > are > + recorded and FALSE is returned. > + > + @param[in] Expression The BOOLEAN result of the expression > evaluation. > + @param[in] FunctionName Null-terminated ASCII string of the functio= n > + executing the assert macro. > + @param[in] LineNumber The source file line number of the assert m= acro. > + @param[in] FileName Null-terminated ASCII string of the filenam= e > + executing the assert macro. > + @param[in] Description Null-terminated ASCII string of the express= ion > being > + evaluated. > + > + @retval TRUE Expression is TRUE. > + @retval FALSE Expression is FALSE. > +**/ > +BOOLEAN > +EFIAPI > +UnitTestAssertTrue ( > + IN BOOLEAN Expression, > + IN CONST CHAR8 *FunctionName, > + IN UINTN LineNumber, > + IN CONST CHAR8 *FileName, > + IN CONST CHAR8 *Description > + ); > + > +/** > + If Expression is FALSE, then TRUE is returned. > + If Expression is TRUE, then an assert is triggered and the location o= f the > + assert provided by FunctionName, LineNumber, FileName, and Descriptio= n > are > + recorded and FALSE is returned. > + > + @param[in] Expression The BOOLEAN result of the expression > evaluation. > + @param[in] FunctionName Null-terminated ASCII string of the functio= n > + executing the assert macro. > + @param[in] LineNumber The source file line number of the assert m= acro. > + @param[in] FileName Null-terminated ASCII string of the filenam= e > + executing the assert macro. > + @param[in] Description Null-terminated ASCII string of the express= ion > being > + evaluated. > + > + @retval TRUE Expression is FALSE. > + @retval FALSE Expression is TRUE. > +**/ > +BOOLEAN > +EFIAPI > +UnitTestAssertFalse ( > + IN BOOLEAN Expression, > + IN CONST CHAR8 *FunctionName, > + IN UINTN LineNumber, > + IN CONST CHAR8 *FileName, > + IN CONST CHAR8 *Description > + ); > + > +/** > + If Status is not an EFI_ERROR(), then TRUE is returned. > + If Status is an EFI_ERROR(), then an assert is triggered and the loca= tion of > + the assert provided by FunctionName, LineNumber, FileName, and > Description are > + recorded and FALSE is returned. > + > + @param[in] Status The EFI_STATUS value to evaluate. > + @param[in] FunctionName Null-terminated ASCII string of the functio= n > + executing the assert macro. > + @param[in] LineNumber The source file line number of the assert m= acro. > + @param[in] FileName Null-terminated ASCII string of the filenam= e > + executing the assert macro. > + @param[in] Description Null-terminated ASCII string of the status > + expression being evaluated. > + > + @retval TRUE Status is not an EFI_ERROR(). > + @retval FALSE Status is an EFI_ERROR(). > +**/ > +BOOLEAN > +EFIAPI > +UnitTestAssertNotEfiError ( > + IN EFI_STATUS Status, > + IN CONST CHAR8 *FunctionName, > + IN UINTN LineNumber, > + IN CONST CHAR8 *FileName, > + IN CONST CHAR8 *Description > + ); > + > +/** > + If ValueA is equal ValueB, then TRUE is returned. > + If ValueA is not equal to ValueB, then an assert is triggered and the > location > + of the assert provided by FunctionName, LineNumber, FileName, > DescriptionA, > + and DescriptionB are recorded and FALSE is returned. > + > + @param[in] ValueA 64-bit value. > + @param[in] ValueB 64-bit value. > + @param[in] FunctionName Null-terminated ASCII string of the functio= n > + executing the assert macro. > + @param[in] LineNumber The source file line number of the assert m= acro. > + @param[in] FileName Null-terminated ASCII string of the filenam= e > + executing the assert macro. > + @param[in] DescriptionA Null-terminated ASCII string that is a > description > + of ValueA. > + @param[in] DescriptionB Null-terminated ASCII string that is a > description > + of ValueB. > + > + @retval TRUE ValueA is equal to ValueB. > + @retval FALSE ValueA is not equal to ValueB. > +**/ > +BOOLEAN > +EFIAPI > +UnitTestAssertEqual ( > + IN UINT64 ValueA, > + IN UINT64 ValueB, > + IN CONST CHAR8 *FunctionName, > + IN UINTN LineNumber, > + IN CONST CHAR8 *FileName, > + IN CONST CHAR8 *DescriptionA, > + IN CONST CHAR8 *DescriptionB > + ); > + > +/** > + If the contents of BufferA are identical to the contents of BufferB, = then > TRUE > + is returned. If the contents of BufferA are not identical to the con= tents of > + BufferB, then an assert is triggered and the location of the assert p= rovided > + by FunctionName, LineNumber, FileName, DescriptionA, and DescriptionB > are > + recorded and FALSE is returned. > + > + @param[in] BufferA Pointer to a buffer for comparison. > + @param[in] BufferB Pointer to a buffer for comparison. > + @param[in] Length Number of bytes to compare in BufferA and > BufferB. > + @param[in] FunctionName Null-terminated ASCII string of the functio= n > + executing the assert macro. > + @param[in] LineNumber The source file line number of the assert m= acro. > + @param[in] FileName Null-terminated ASCII string of the filenam= e > + executing the assert macro. > + @param[in] DescriptionA Null-terminated ASCII string that is a > description > + of BufferA. > + @param[in] DescriptionB Null-terminated ASCII string that is a > description > + of BufferB. > + > + @retval TRUE The contents of BufferA are identical to the contents= of > + BufferB. > + @retval FALSE The contents of BufferA are not identical to the cont= ents > of > + BufferB. > +**/ > +BOOLEAN > +EFIAPI > +UnitTestAssertMemEqual ( > + IN VOID *BufferA, > + IN VOID *BufferB, > + IN UINTN Length, > + IN CONST CHAR8 *FunctionName, > + IN UINTN LineNumber, > + IN CONST CHAR8 *FileName, > + IN CONST CHAR8 *DescriptionA, > + IN CONST CHAR8 *DescriptionB > + ); > + > +/** > + If ValueA is not equal ValueB, then TRUE is returned. > + If ValueA is equal to ValueB, then an assert is triggered and the loc= ation > + of the assert provided by FunctionName, LineNumber, FileName, > DescriptionA > + and DescriptionB are recorded and FALSE is returned. > + > + @param[in] ValueA 64-bit value. > + @param[in] ValueB 64-bit value. > + @param[in] FunctionName Null-terminated ASCII string of the functio= n > + executing the assert macro. > + @param[in] LineNumber The source file line number of the assert m= acro. > + @param[in] FileName Null-terminated ASCII string of the filenam= e > + executing the assert macro. > + @param[in] DescriptionA Null-terminated ASCII string that is a > description > + of ValueA. > + @param[in] DescriptionB Null-terminated ASCII string that is a > description > + of ValueB. > + > + @retval TRUE ValueA is not equal to ValueB. > + @retval FALSE ValueA is equal to ValueB. > +**/ > +BOOLEAN > +EFIAPI > +UnitTestAssertNotEqual ( > + IN UINT64 ValueA, > + IN UINT64 ValueB, > + IN CONST CHAR8 *FunctionName, > + IN UINTN LineNumber, > + IN CONST CHAR8 *FileName, > + IN CONST CHAR8 *DescriptionA, > + IN CONST CHAR8 *DescriptionB > + ); > + > +/** > + If Status is equal to Expected, then TRUE is returned. > + If Status is not equal to Expected, then an assert is triggered and t= he > + location of the assert provided by FunctionName, LineNumber, FileName= , > and > + Description are recorded and FALSE is returned. > + > + @param[in] Status EFI_STATUS value returned from an API under= test. > + @param[in] Expected The expected EFI_STATUS return value from a= n > API > + under test. > + @param[in] FunctionName Null-terminated ASCII string of the functio= n > + executing the assert macro. > + @param[in] LineNumber The source file line number of the assert m= acro. > + @param[in] FileName Null-terminated ASCII string of the filenam= e > + executing the assert macro. > + @param[in] Description Null-terminated ASCII string that is a desc= ription > + of Status. > + > + @retval TRUE Status is equal to Expected. > + @retval FALSE Status is not equal to Expected. > +**/ > +BOOLEAN > +EFIAPI > +UnitTestAssertStatusEqual ( > + IN EFI_STATUS Status, > + IN EFI_STATUS Expected, > + IN CONST CHAR8 *FunctionName, > + IN UINTN LineNumber, > + IN CONST CHAR8 *FileName, > + IN CONST CHAR8 *Description > + ); > + > +/** > + If Pointer is not equal to NULL, then TRUE is returned. > + If Pointer is equal to NULL, then an assert is triggered and the loca= tion of > + the assert provided by FunctionName, LineNumber, FileName, and > PointerName > + are recorded and FALSE is returned. > + > + @param[in] Pointer Pointer value to be checked against NULL. > + @param[in] Expected The expected EFI_STATUS return value from a > function > + under test. > + @param[in] FunctionName Null-terminated ASCII string of the functio= n > + executing the assert macro. > + @param[in] LineNumber The source file line number of the assert m= acro. > + @param[in] FileName Null-terminated ASCII string of the filenam= e > + executing the assert macro. > + @param[in] PointerName Null-terminated ASCII string that is a > description > + of Pointer. > + > + @retval TRUE Pointer is not equal to NULL. > + @retval FALSE Pointer is equal to NULL. > +**/ > +BOOLEAN > +EFIAPI > +UnitTestAssertNotNull ( > + IN VOID *Pointer, > + IN CONST CHAR8 *FunctionName, > + IN UINTN LineNumber, > + IN CONST CHAR8 *FileName, > + IN CONST CHAR8 *PointerName > + ); > + > +/** > + Test logging macro that records an ERROR message in the test framewor= k > log. > + Record is associated with the currently executing test case. > + > + @param[in] Format Formatting string following the format defined in > + MdePkg/Include/Library/PrintLib.h. > + @param[in] ... Print args. > +**/ > +#define UT_LOG_ERROR(Format, ...) \ > + UnitTestLog (UNIT_TEST_LOG_LEVEL_ERROR, Format, ##__VA_ARGS__) > + > +/** > + Test logging macro that records a WARNING message in the test > framework log. > + Record is associated with the currently executing test case. > + > + @param[in] Format Formatting string following the format defined in > + MdePkg/Include/Library/PrintLib.h. > + @param[in] ... Print args. > +**/ > +#define UT_LOG_WARNING(Format, ...) \ > + UnitTestLog (UNIT_TEST_LOG_LEVEL_WARN, Format, ##__VA_ARGS__) > + > +/** > + Test logging macro that records an INFO message in the test framework > log. > + Record is associated with the currently executing test case. > + > + @param[in] Format Formatting string following the format defined in > + MdePkg/Include/Library/PrintLib.h. > + @param[in] ... Print args. > +**/ > +#define UT_LOG_INFO(Format, ...) \ > + UnitTestLog (UNIT_TEST_LOG_LEVEL_INFO, Format, ##__VA_ARGS__) > + > +/** > + Test logging macro that records a VERBOSE message in the test > framework log. > + Record is associated with the currently executing test case. > + > + @param[in] Format Formatting string following the format defined in > + MdePkg/Include/Library/PrintLib.h. > + @param[in] ... Print args. > +**/ > +#define UT_LOG_VERBOSE(Format, ...) \ > + UnitTestLog (UNIT_TEST_LOG_LEVEL_VERBOSE, Format, ##__VA_ARGS__) > + > +/** > + Test logging function that records a messages in the test framework l= og. > + Record is associated with the currently executing test case. > + > + @param[in] ErrorLevel The error level of the unit test log message. > + @param[in] Format Formatting string following the format define= d in > the > + MdePkg/Include/Library/PrintLib.h. > + @param[in] ... Print args. > +**/ > +VOID > +EFIAPI > +UnitTestLog ( > + IN UINTN ErrorLevel, > + IN CONST CHAR8 *Format, > + ... > + ); > + > +#endif > diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec > index d022cc5e3e..ac1f5339af 100644 > --- a/MdePkg/MdePkg.dec > +++ b/MdePkg/MdePkg.dec > @@ -244,6 +244,10 @@ [LibraryClasses] > ## @libraryclass Module entry point library for standalone MM drive= rs. > > StandaloneMmDriverEntryPoint|Include/Library/StandaloneMmDriverEntryP > oint.h > > + ## @libraryclass Provides a unit test framework > + # > + UnitTestLib|Include/Library/UnitTestLib.h > + > [LibraryClasses.IA32, LibraryClasses.X64] > ## @libraryclass Abstracts both S/W SMI generation and detection. > ## > -- > 2.21.0.windows.1 > > >=20 --_000_CY4PR21MB0743F68EE69A56DD7F0C6F5FEF1C0CY4PR21MB0743namp_ Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable

@Sean, how would th= ese have been missed by the spell checker?

 

- Bret

 


From: Wu, Hao A <hao.a.= wu@intel.com>
Sent: Thursday, February 6, 2020 5:22:21 PM
To: devel@edk2.groups.io <devel@edk2.groups.io>; Kinney, Mich= ael D <michael.d.kinney@intel.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>; Sean Brogan = <sean.brogan@microsoft.com>; Bret Barkelew <Bret.Barkelew@microsof= t.com>; Gao, Liming <liming.gao@intel.com>
Subject: [EXTERNAL] RE: [edk2-devel] [Patch 03/11] MdePkg/Include/L= ibrary: Add UnitTestLib class
 
A couple of typos (some of them occur multiple ti= mes) in UnitTestLib.h:

Funtions -> Functions
paramter -> parameter
Null-terminaled -> Null-terminated
dispached -> dispatched
storage devide -> storage device

With them addressed,
Reviewed-by: Hao A Wu <hao.a.wu@intel.com>

Best Regards,
Hao Wu


> -----Original Message-----
> From: devel@edk2.groups.io [m= ailto:devel@edk2.groups.io] On Behalf Of
> Michael D Kinney
> Sent: Friday, January 24, 2020 10:10 AM
> To: devel@edk2.groups.io
> Cc: Bret Barkelew; Sean Brogan; Bret Barkelew; Gao, Liming
> Subject: [edk2-devel] [Patch 03/11] MdePkg/Include/Library: Add UnitT= estLib
> class
>
> From: Bret Barkelew <brbarkel@microsoft.com>
>
> Add UnitTestLib class to MdePkg that provides services
> and macros to implement unit tests.  These services and
> macros support the following features:
>
> * Create a Unit Test Framework
> * Add a Unit Test Suite to a Unit Test Framework
>   + Support optional step that executes before a Unit >     Test Suite is started.
>   + Support optional step that executes after a Unit >     Test Suite is finished.
> * Add a Unit Test to a Unit Test Suite
>   + Support optional step that executes before a Unit >     Test is started.
>   + Support optional step that executes after a Unit >     Test is finished.
> * Run all unit tests added to a Unit Test Framework
> * Save Unit Test Framework state to persistent storage
> * Support assertion checks in a unit test for TRUE, FALSE,
>   EQUAL, MEM_EQUAL, NOT_EFI_ERROR, STATUS_EQUAL, and NOT_NU= LL.
> * Support generation of log messages at ERROR, WARN, INFO,
>   and VERBOSE levels.
>
> Cc: Sean Brogan <sean.brogan@microsoft.com>
> Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> > ---
>  MdePkg/Include/Library/UnitTestLib.h | 757
> ++++++++++++++= ;+++++++++++++
>  MdePkg/MdePkg.dec       &nbs= p;            | = ;  4 +
>  2 files changed, 761 insertions(+)
>  create mode 100644 MdePkg/Include/Library/UnitTestLib.h
>
> diff --git a/MdePkg/Include/Library/UnitTestLib.h
> b/MdePkg/Include/Library/UnitTestLib.h
> new file mode 100644
> index 0000000000..757ebaf6ba
> --- /dev/null
> +++ b/MdePkg/Include/Library/UnitTestLib.h
> @@ -0,0 +1,757 @@
> +/** @file
> +  Provides a unit test framework.  This allows tests t= o focus on testing logic
> +  and the framework to focus on runnings, reporting, statis= tics, etc.
> +
> +  Copyright (c) Microsoft Corporation.<BR>
> +  Copyright (c) 2020, Intel Corporation. All rights reserve= d.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __UNIT_TEST_LIB_H__
> +#define __UNIT_TEST_LIB_H__
> +
> +///
> +/// Unit Test Status
> +///
> +typedef UINT32  UNIT_TEST_STATUS;
> +#define UNIT_TEST_PASSED      &nbs= p;            &= nbsp;  (0)
> +#define UNIT_TEST_ERROR_PREREQUISITE_NOT_MET  (1)
> +#define UNIT_TEST_ERROR_TEST_FAILED     = ;      (2)
> +#define UNIT_TEST_ERROR_CLEANUP_FAILED    &n= bsp;   (3)
> +#define UNIT_TEST_SKIPPED      &nb= sp;            =   (0xFFFFFFFD)
> +#define UNIT_TEST_RUNNING      &nb= sp;            =   (0xFFFFFFFE)
> +#define UNIT_TEST_PENDING      &nb= sp;            =   (0xFFFFFFFF)
> +
> +///
> +/// Declare PcdUnitTestLogLevel bits and UnitTestLog() ErrorLeve= l
> parameter.
> +///
> +#define UNIT_TEST_LOG_LEVEL_ERROR    BIT0
> +#define UNIT_TEST_LOG_LEVEL_WARN     BIT1 > +#define UNIT_TEST_LOG_LEVEL_INFO     BIT2 > +#define UNIT_TEST_LOG_LEVEL_VERBOSE  BIT3
> +
> +///
> +/// Unit Test Framework Handle
> +///
> +struct UNIT_TEST_FRAMEWORK_OBJECT;
> +typedef struct UNIT_TEST_FRAMEWORK_OBJECT
> *UNIT_TEST_FRAMEWORK_HANDLE;
> +
> +///
> +/// Unit Test Suite Handle
> +///
> +struct UNIT_TEST_SUITE_OBJECT;
> +typedef struct UNIT_TEST_SUITE_OBJECT  *UNIT_TEST_SUITE_HAN= DLE;
> +
> +///
> +/// Unit Test Handle
> +///
> +struct UNIT_TEST_OBJECT;
> +typedef struct UNIT_TEST_OBJECT  *UNIT_TEST_HANDLE;
> +
> +///
> +/// Unit Test Context
> +///
> +typedef VOID*  UNIT_TEST_CONTEXT;
> +
> +/**
> +  The prototype for a single UnitTest case function.
> +
> +  Funtions with this prototype are registered to be dispatc= hed by the
> +  UnitTest framework, and results are recorded as test Pass= or Fail.
> +
> +  @param[in]  Context    [Optional] An = optional paramter that enables:      
> +          &nbs= p;            &= nbsp; 1) test-case reuse with varied parameters and
> +          &nbs= p;            &= nbsp; 2) test-case re-entry for Target tests that need a
> +          &nbs= p;            &= nbsp; reboot.  This parameter is a VOID* and it is the
> +          &nbs= p;            &= nbsp; responsibility of the test author to ensure that the
> +          &nbs= p;            &= nbsp; contents are well understood by all test cases that may
> +          &nbs= p;            &= nbsp; consume it.
> +
> +  @retval  UNIT_TEST_PASSED    &nb= sp;        The Unit test has completed a= nd the
> test
> +          &nbs= p;            &= nbsp;           &nbs= p;    case was successful.
> +  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test ca= se assertion has failed.
> +
> +**/
> +typedef
> +UNIT_TEST_STATUS
> +(EFIAPI *UNIT_TEST_FUNCTION)(
> +  IN UNIT_TEST_CONTEXT  Context
> +  );
> +
> +/**
> +  Unit-Test Prerequisite Function pointer type.
> +
> +  Funtions with this prototype are registered to be dispatc= hed by the unit
> test
> +  framework prior to a given test case. If this prereq func= tion returns
> +  UNIT_TEST_ERROR_PREREQUISITE_NOT_MET, the test case will = be
> skipped.
> +
> +  @param[in]  Context    [Optional] An = optional paramter that enables:
> +          &nbs= p;            &= nbsp; 1) test-case reuse with varied parameters and
> +          &nbs= p;            &= nbsp; 2) test-case re-entry for Target tests that need a
> +          &nbs= p;            &= nbsp; reboot.  This parameter is a VOID* and it is the
> +          &nbs= p;            &= nbsp; responsibility of the test author to ensure that the
> +          &nbs= p;            &= nbsp; contents are well understood by all test cases that may
> +          &nbs= p;            &= nbsp; consume it.
> +
> +  @retval  UNIT_TEST_PASSED    &nb= sp;            =      Unit test case prerequisites
> +          &nbs= p;            &= nbsp;           &nbs= p;             = are met.
> +  @retval  UNIT_TEST_ERROR_PREREQUISITE_NOT_MET  = Test case should
> be skipped.
> +
> +**/
> +typedef
> +UNIT_TEST_STATUS
> +(EFIAPI *UNIT_TEST_PREREQUISITE)(
> +  IN UNIT_TEST_CONTEXT  Context
> +  );
> +
> +/**
> +  Unit-Test Cleanup (after) function pointer type.
> +
> +  Funtions with this prototype are registered to be dispatc= hed by the
> +  unit test framework after a given test case. This will be= called even if the
> +  test case returns an error, but not if the prerequisite f= ails and the test is
> +  skipped.  The purpose of this function is to clean u= p any global state or
> +  test data.
> +
> +  @param[in]  Context    [Optional] An = optional paramter that enables:
> +          &nbs= p;            &= nbsp; 1) test-case reuse with varied parameters and
> +          &nbs= p;            &= nbsp; 2) test-case re-entry for Target tests that need a
> +          &nbs= p;            &= nbsp; reboot.  This parameter is a VOID* and it is the
> +          &nbs= p;            &= nbsp; responsibility of the test author to ensure that the
> +          &nbs= p;            &= nbsp; contents are well understood by all test cases that may
> +          &nbs= p;            &= nbsp; consume it.
> +
> +  @retval  UNIT_TEST_PASSED    &nb= sp;           Test case c= leanup succeeded.
> +  @retval  UNIT_TEST_ERROR_CLEANUP_FAILED  Test c= ase cleanup failed.
> +
> +**/
> +typedef
> +VOID
> +(EFIAPI *UNIT_TEST_CLEANUP)(
> +  IN UNIT_TEST_CONTEXT  Context
> +  );
> +
> +/**
> +  Unit-Test Test Suite Setup (before) function pointer type= . Funtions with this
> +  prototype are registered to be dispatched by the UnitTest= framework prior
> to
> +  running any of the test cases in a test suite.  It w= ill only be run once at
> +  the beginning of the suite (not prior to each case).
> +
> +  The purpose of this function is to set up any global stat= e or test data.
> +**/
> +typedef
> +VOID
> +(EFIAPI *UNIT_TEST_SUITE_SETUP)(
> +  VOID
> +  );
> +
> +/**
> +  Unit-Test Test Suite Teardown (after) function pointer ty= pe.  Funtions with
> +  this prototype are registered to be dispatched by the Uni= tTest framework
> after
> +  running all of the test cases in a test suite.  It w= ill only be run once at
> +  the end of the suite.
> +
> +  The purpose of this function is to clean up any global st= ate or test data.
> +**/
> +typedef
> +VOID
> +(EFIAPI *UNIT_TEST_SUITE_TEARDOWN)(
> +  VOID
> +  );
> +
> +/**
> +  Method to Initialize the Unit Test framework.  This = function registers the
> +  test name and also initializes the internal state of the = test framework to
> +  receive any new suites and tests.
> +
> +  @param[out]  FrameworkHandle  Unit test framewo= rk to be created.
> +  @param[in]   Title     = ;       Null-terminated ASCII string that is = the user
> +          &nbs= p;            &= nbsp;        friendly name of the framew= ork. String is
> +          &nbs= p;            &= nbsp;        copied.
> +  @param[in]   ShortTitle    =    Null-terminaled ASCII short string that is the
> +          &nbs= p;            &= nbsp;        short name of the framework= with no spaces.
> +          &nbs= p;            &= nbsp;        String is copied.
> +  @param[in]   VersionString    Nu= ll-terminaled ASCII version string for the
> +          &nbs= p;            &= nbsp;        framework. String is copied= .
> +
> +  @retval  EFI_SUCCESS     &n= bsp;      The unit test framework was initialized.=
> +  @retval  EFI_INVALID_PARAMETER  FrameworkHandle= is NULL.
> +  @retval  EFI_INVALID_PARAMETER  Title is NULL.<= br> > +  @retval  EFI_INVALID_PARAMETER  ShortTitle is N= ULL.
> +  @retval  EFI_INVALID_PARAMETER  VersionString i= s NULL.
> +  @retval  EFI_INVALID_PARAMETER  ShortTitle is i= nvalid.
> +  @retval  EFI_OUT_OF_RESOURCES   There are = not enough resources
> available to
> +          &nbs= p;            &= nbsp;          initialize the = unit test framework.
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitUnitTestFramework (
> +  OUT UNIT_TEST_FRAMEWORK_HANDLE  *FrameworkHandle, > +  IN  CHAR8       &= nbsp;           &nbs= p;   *Title,
> +  IN  CHAR8       &= nbsp;           &nbs= p;   *ShortTitle,
> +  IN  CHAR8       &= nbsp;           &nbs= p;   *VersionString
> +  );
> +
> +/**
> +  Registers a Unit Test Suite in the Unit Test Framework. > +  At least one test suite must be registered, because all t= est cases must be
> +  within a unit test suite.
> +
> +  @param[out]  SuiteHandle    &nbs= p; Unit test suite to create
> +  @param[in]   FrameworkHandle  Unit test fr= amework to add unit test suite
> to
> +  @param[in]   Title     = ;       Null-terminated ASCII string that is = the user
> +          &nbs= p;            &= nbsp;        friendly name of the test s= uite.  String is
> +          &nbs= p;            &= nbsp;        copied.
> +  @param[in]   Name     =         Null-terminated ASCII string tha= t is the short
> +          &nbs= p;            &= nbsp;        name of the test suite with= no spaces.  String
> +          &nbs= p;            &= nbsp;        is copied.
> +  @param[in]   Setup     = ;       Setup function, runs before suite.&nb= sp; This is an
> +          &nbs= p;            &= nbsp;        optional parameter that may= be NULL.
> +  @param[in]   Teardown    &n= bsp;    Teardown function, runs after suite.  This is > an
> +          &nbs= p;            &= nbsp;        optional parameter that may= be NULL.
> +
> +  @retval  EFI_SUCCESS     &n= bsp;      The unit test suite was created.
> +  @retval  EFI_INVALID_PARAMETER  SuiteHandle is = NULL.
> +  @retval  EFI_INVALID_PARAMETER  FrameworkHandle= is NULL.
> +  @retval  EFI_INVALID_PARAMETER  Title is NULL.<= br> > +  @retval  EFI_INVALID_PARAMETER  Name is NULL. > +  @retval  EFI_OUT_OF_RESOURCES   There are = not enough resources
> available to
> +          &nbs= p;            &= nbsp;          initialize the = unit test suite.
> +**/
> +EFI_STATUS
> +EFIAPI
> +CreateUnitTestSuite (
> +  OUT UNIT_TEST_SUITE_HANDLE      = *SuiteHandle,
> +  IN  UNIT_TEST_FRAMEWORK_HANDLE  FrameworkHandle= ,
> +  IN  CHAR8       &= nbsp;           &nbs= p;   *Title,
> +  IN  CHAR8       &= nbsp;           &nbs= p;   *Name,
> +  IN  UNIT_TEST_SUITE_SETUP    &nb= sp;  Setup     OPTIONAL,
> +  IN  UNIT_TEST_SUITE_TEARDOWN    Teard= own  OPTIONAL
> +  );
> +
> +/**
> +  Adds test case to Suite
> +
> +  @param[in]  SuiteHandle   Unit test suite = to add test to.
> +  @param[in]  Description   Null-terminated = ASCII string that is the user
> +          &nbs= p;            &= nbsp;    friendly description of a test.  String is cop= ied.
> +  @param[in]  Name      =     Null-terminated ASCII string that is the short
> name
> +          &nbs= p;            &= nbsp;    of the test with no spaces.  String is copied.=
> +  @param[in]  Function      U= nit test function.
> +  @param[in]  Prerequisite  Prerequisite function= , runs before test.  This is
> +          &nbs= p;            &= nbsp;    an optional parameter that may be NULL.
> +  @param[in]  CleanUp     &nb= sp; Clean up function, runs after test.  This is an
> +          &nbs= p;            &= nbsp;    optional parameter that may be NULL.
> +  @param[in]  Context     &nb= sp; Pointer to context.    This is an optional
> parameter
> +          &nbs= p;            &= nbsp;    that may be NULL.
> +
> +  @retval  EFI_SUCCESS     &n= bsp;      The unit test case was added to Suite. > +  @retval  EFI_INVALID_PARAMETER  SuiteHandle is = NULL.
> +  @retval  EFI_INVALID_PARAMETER  Description is = NULL.
> +  @retval  EFI_INVALID_PARAMETER  Name is NULL. > +  @retval  EFI_INVALID_PARAMETER  Function is NUL= L.
> +  @retval  EFI_OUT_OF_RESOURCES   There are = not enough resources
> available to
> +          &nbs= p;            &= nbsp;          add the unit te= st case to Suite.
> +**/
> +EFI_STATUS
> +EFIAPI
> +AddTestCase (
> +  IN UNIT_TEST_SUITE_HANDLE  SuiteHandle,
> +  IN CHAR8        &= nbsp;          *Description, > +  IN CHAR8        &= nbsp;          *Name,
> +  IN UNIT_TEST_FUNCTION      Funct= ion,
> +  IN UNIT_TEST_PREREQUISITE  Prerequisite  OPTION= AL,
> +  IN UNIT_TEST_CLEANUP       = CleanUp       OPTIONAL,
> +  IN UNIT_TEST_CONTEXT       = Context       OPTIONAL
> +  );
> +
> +/**
> +  Execute all unit test cases in all unit test suites added= to a Framework.
> +
> +  Once a unit test framework is initialized and all unit te= st suites and unit
> +  test cases are registered, this function will cause the u= nit test framework
> to
> +  dispatch all unit test cases in sequence and record the r= esults for reporting.
> +
> +  @param[in]  FrameworkHandle  A handle to the cu= rrent running
> framework that
> +          &nbs= p;            &= nbsp;       dispatched the test.  Necess= ary for recording
> +          &nbs= p;            &= nbsp;       certain test events with the fram= ework.
> +
> +  @retval  EFI_SUCCESS     &n= bsp;      All test cases were dispached.
> +  @retval  EFI_INVALID_PARAMETER  FrameworkHandle= is NULL.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RunAllTestSuites (
> +  IN UNIT_TEST_FRAMEWORK_HANDLE  FrameworkHandle
> +  );
> +
> +/**
> +  Cleanup a test framework.
> +
> +  After tests are run, this will teardown the entire framew= ork and free all
> +  allocated data within.
> +
> +  @param[in]  FrameworkHandle  A handle to the cu= rrent running
> framework that
> +          &nbs= p;            &= nbsp;       dispatched the test.  Necess= ary for recording
> +          &nbs= p;            &= nbsp;       certain test events with the fram= ework.
> +
> +  @retval  EFI_SUCCESS     &n= bsp;      All resources associated with framework<= br> > were
> +          &nbs= p;            &= nbsp;          freed.
> +  @retval  EFI_INVALID_PARAMETER  FrameworkHandle= is NULL.
> +**/
> +EFI_STATUS
> +EFIAPI
> +FreeUnitTestFramework (
> +  IN UNIT_TEST_FRAMEWORK_HANDLE  FrameworkHandle
> +  );
> +
> +/**
> +  Leverages a framework-specific mechanism (see UnitTestPer= sistenceLib if
> you're
> +  a framework author) to save the state of the executing fr= amework along
> with
> +  any allocated data so that the test may be resumed upon r= eentry. A test
> case
> +  should pass any needed context (which, to prevent an infi= nite loop, should
> be
> +  at least the current execution count) which will be saved= by the framework
> and
> +  passed to the test case upon resume.
> +
> +  Generally called from within a test case prior to quittin= g or rebooting.
> +
> +  @param[in]  FrameworkHandle    A hand= le to the current running
> framework that
> +          &nbs= p;            &= nbsp;         dispatched the test.&= nbsp; Necessary for recording
> +          &nbs= p;            &= nbsp;         certain test events w= ith the framework.
> +  @param[in]  ContextToSave    &nb= sp; A buffer of test case-specific data to be
> saved
> +          &nbs= p;            &= nbsp;         along with framework = state.  Will be passed as
> +          &nbs= p;            &= nbsp;         "Context" t= o the test case upon resume.  This
> +          &nbs= p;            &= nbsp;         is an optional parame= ter that may be NULL.
> +  @param[in]  ContextToSaveSize  Size of the Cont= extToSave buffer.
> +
> +  @retval  EFI_SUCCESS     &n= bsp;      The framework state and context were sav= ed.
> +  @retval  EFI_INVALID_PARAMETER  FrameworkHandle= is NULL.
> +  @retval  EFI_INVALID_PARAMETER  ContextToSave i= s not NULL and
> +          &nbs= p;            &= nbsp;          ContextToSaveSi= ze is 0.
> +  @retval  EFI_INVALID_PARAMETER  ContextToSave i= s >=3D 4GB.
> +  @retval  EFI_OUT_OF_RESOURCES   There are = not enough resources
> available to
> +          &nbs= p;            &= nbsp;          save the framew= ork and context state.
> +  @retval  EFI_DEVICE_ERROR    &nb= sp;  The framework and context state could
> not be
> +          &nbs= p;            &= nbsp;          saved to a pers= istent storage devide due to a
> +          &nbs= p;            &= nbsp;          device error. > +**/
> +EFI_STATUS
> +EFIAPI
> +SaveFrameworkState (
> +  IN UNIT_TEST_FRAMEWORK_HANDLE  FrameworkHandle,
> +  IN UNIT_TEST_CONTEXT      &= nbsp;    ContextToSave     OPTIONAL,
> +  IN UINTN        &= nbsp;           &nbs= p;  ContextToSaveSize
> +  );
> +
> +/**
> +  This macro uses the framework assertion logic to check an= expression for
> +  "TRUE". If the expression evaluates to TRUE, ex= ecution continues.
> +  Otherwise, the test case immediately returns
> UNIT_TEST_ERROR_TEST_FAILED.
> +
> +  @param[in]  Expression  Expression to be evalua= ted for TRUE.
> +**/
> +#define UT_ASSERT_TRUE(Expression)     =             &nb= sp;            =             &nb= sp;            = \
> +  if(!UnitTestAssertTrue ((Expression), __FUNCTION__, __LIN= E__, __FILE__,
> #Expression)) { \
> +    return UNIT_TEST_ERROR_TEST_FAILED; &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp;           \
> +  }
> +
> +/**
> +  This macro uses the framework assertion logic to check an= expression for
> +  "FALSE". If the expression evaluates to FALSE, = execution continues.
> +  Otherwise, the test case immediately returns
> UNIT_TEST_ERROR_TEST_FAILED.
> +
> +  @param[in]  Expression  Expression to be evalua= ted for FALSE.
> +**/
> +#define UT_ASSERT_FALSE(Expression)     = ;            &n= bsp;            = ;            &n= bsp;            = ; \
> +  if(!UnitTestAssertFalse ((Expression), __FUNCTION__, __LI= NE__, __FILE__,
> #Expression)) { \
> +    return UNIT_TEST_ERROR_TEST_FAILED; &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp;            \ > +  }
> +
> +/**
> +  This macro uses the framework assertion logic to check wh= ether two
> simple
> +  values are equal.  If the values are equal, executio= n continues.
> +  Otherwise, the test case immediately returns
> UNIT_TEST_ERROR_TEST_FAILED.
> +
> +  @param[in]  ValueA  Value to be compared for eq= uality (64-bit
> comparison).
> +  @param[in]  ValueB  Value to be compared for eq= uality (64-bit
> comparison).
> +**/
> +#define UT_ASSERT_EQUAL(ValueA, ValueB)
> \
> +  if(!UnitTestAssertEqual ((UINT64)(ValueA), (UINT64)(Value= B),
> __FUNCTION__, __LINE__, __FILE__, #ValueA, #ValueB)) { \
> +    return UNIT_TEST_ERROR_TEST_FAILED;
> \
> +  }
> +
> +/**
> +  This macro uses the framework assertion logic to check wh= ether two
> memory
> +  buffers are equal.  If the buffers are equal, execut= ion continues.
> +  Otherwise, the test case immediately returns
> UNIT_TEST_ERROR_TEST_FAILED.
> +
> +  @param[in]  BufferA  Pointer to a buffer for co= mparison.
> +  @param[in]  BufferB  Pointer to a buffer for co= mparison.
> +  @param[in]  Length   Number of bytes to co= mpare in BufferA and BufferB.
> +**/
> +#define UT_ASSERT_MEM_EQUAL(BufferA, BufferB, Length)
> \
> +  if(!UnitTestAssertMemEqual ((VOID *)(UINTN)(BufferA), (VO= ID
> *)(UINTN)(BufferB), (UINTN)Length, __FUNCTION__, __LINE__, __FILE__,<= br> > #BufferA, #BufferB)) { \
> +    return UNIT_TEST_ERROR_TEST_FAILED;
> \
> +  }
> +
> +/**
> +  This macro uses the framework assertion logic to check wh= ether two
> simple
> +  values are non-equal.  If the values are non-equal, = execution continues.
> +  Otherwise, the test case immediately returns
> UNIT_TEST_ERROR_TEST_FAILED.
> +
> +  @param[in]  ValueA  Value to be compared for in= equality (64-bit
> comparison).
> +  @param[in]  ValueB  Value to be compared for in= equality (64-bit
> comparison).
> +**/
> +#define UT_ASSERT_NOT_EQUAL(ValueA, ValueB)
> \
> +  if(!UnitTestAssertNotEqual ((UINT64)(ValueA), (UINT64)(Va= lueB),
> __FUNCTION__, __LINE__, __FILE__, #ValueA, #ValueB)) { \
> +    return UNIT_TEST_ERROR_TEST_FAILED;
> \
> +  }
> +
> +/**
> +  This macro uses the framework assertion logic to check wh= ether an
> EFI_STATUS
> +  value is !EFI_ERROR().  If the status is !EFI_ERROR(= ), execution continues.
> +  Otherwise, the test case immediately returns
> UNIT_TEST_ERROR_TEST_FAILED.
> +
> +  @param[in]  Status  EFI_STATUS value to check.<= br> > +**/
> +#define UT_ASSERT_NOT_EFI_ERROR(Status)    &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;      \
> +  if(!UnitTestAssertNotEfiError ((Status), __FUNCTION__, __= LINE__,
> __FILE__, #Status)) { \
> +    return UNIT_TEST_ERROR_TEST_FAILED; &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp;        \
> +  }
> +
> +/**
> +  This macro uses the framework assertion logic to check wh= ether two
> EFI_STATUS
> +  values are equal.  If the values are equal, executio= n continues.
> +  Otherwise, the test case immediately returns
> UNIT_TEST_ERROR_TEST_FAILED.
> +
> +  @param[in]  Status    EFI_STATUS valu= es to compare for equality.
> +  @param[in]  Expected  EFI_STATUS values to comp= are for equality.
> +**/
> +#define UT_ASSERT_STATUS_EQUAL(Status, Expected)
> \
> +  if(!UnitTestAssertStatusEqual ((Status), (Expected), __FU= NCTION__,
> __LINE__, __FILE__, #Status)) { \
> +    return UNIT_TEST_ERROR_TEST_FAILED;
> \
> +  }
> +
> +/**
> +  This macro uses the framework assertion logic to check wh= ether a pointer
> is
> +  not NULL.  If the pointer is not NULL, execution con= tinues. Otherwise, the
> +  test case immediately returns UNIT_TEST_ERROR_TEST_FAILED= .
> +
> +  @param[in]  Pointer  Pointer to be checked agai= nst NULL.
> +**/
> +#define UT_ASSERT_NOT_NULL(Pointer)     = ;            &n= bsp;            = ;            &n= bsp;       \
> +  if(!UnitTestAssertNotNull ((Pointer), __FUNCTION__, __LIN= E__, __FILE__,
> #Pointer)) { \
> +    return UNIT_TEST_ERROR_TEST_FAILED; &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp;      \
> +  }
> +
> +/**
> +  If Expression is TRUE, then TRUE is returned.
> +  If Expression is FALSE, then an assert is triggered and t= he location of the
> +  assert provided by FunctionName, LineNumber, FileName, an= d Description
> are
> +  recorded and FALSE is returned.
> +
> +  @param[in]  Expression    The BOOLEAN= result of the expression
> evaluation.
> +  @param[in]  FunctionName  Null-terminated ASCII= string of the function
> +          &nbs= p;            &= nbsp;    executing the assert macro.
> +  @param[in]  LineNumber    The source = file line number of the assert macro.
> +  @param[in]  FileName      N= ull-terminated ASCII string of the filename
> +          &nbs= p;            &= nbsp;    executing the assert macro.
> +  @param[in]  Description   Null-terminated = ASCII string of the expression
> being
> +          &nbs= p;            &= nbsp;    evaluated.
> +
> +  @retval  TRUE   Expression is TRUE.
> +  @retval  FALSE  Expression is FALSE.
> +**/
> +BOOLEAN
> +EFIAPI
> +UnitTestAssertTrue (
> +  IN BOOLEAN      Expression,
> +  IN CONST CHAR8  *FunctionName,
> +  IN UINTN        LineNu= mber,
> +  IN CONST CHAR8  *FileName,
> +  IN CONST CHAR8  *Description
> +  );
> +
> +/**
> +  If Expression is FALSE, then TRUE is returned.
> +  If Expression is TRUE, then an assert is triggered and th= e location of the
> +  assert provided by FunctionName, LineNumber, FileName, an= d Description
> are
> +  recorded and FALSE is returned.
> +
> +  @param[in]  Expression    The BOOLEAN= result of the expression
> evaluation.
> +  @param[in]  FunctionName  Null-terminated ASCII= string of the function
> +          &nbs= p;            &= nbsp;    executing the assert macro.
> +  @param[in]  LineNumber    The source = file line number of the assert macro.
> +  @param[in]  FileName      N= ull-terminated ASCII string of the filename
> +          &nbs= p;            &= nbsp;    executing the assert macro.
> +  @param[in]  Description   Null-terminated = ASCII string of the expression
> being
> +          &nbs= p;            &= nbsp;    evaluated.
> +
> +  @retval  TRUE   Expression is FALSE.
> +  @retval  FALSE  Expression is TRUE.
> +**/
> +BOOLEAN
> +EFIAPI
> +UnitTestAssertFalse (
> +  IN BOOLEAN      Expression,
> +  IN CONST CHAR8  *FunctionName,
> +  IN UINTN        LineNu= mber,
> +  IN CONST CHAR8  *FileName,
> +  IN CONST CHAR8  *Description
> +  );
> +
> +/**
> +  If Status is not an EFI_ERROR(), then TRUE is returned. > +  If Status is an EFI_ERROR(), then an assert is triggered = and the location of
> +  the assert provided by FunctionName, LineNumber, FileName= , and
> Description are
> +  recorded and FALSE is returned.
> +
> +  @param[in]  Status     &nbs= p;  The EFI_STATUS value to evaluate.
> +  @param[in]  FunctionName  Null-terminated ASCII= string of the function
> +          &nbs= p;            &= nbsp;    executing the assert macro.
> +  @param[in]  LineNumber    The source = file line number of the assert macro.
> +  @param[in]  FileName      N= ull-terminated ASCII string of the filename
> +          &nbs= p;            &= nbsp;    executing the assert macro.
> +  @param[in]  Description   Null-terminated = ASCII string of the status
> +          &nbs= p;            &= nbsp;    expression being evaluated.
> +
> +  @retval  TRUE   Status is not an EFI_ERROR= ().
> +  @retval  FALSE  Status is an EFI_ERROR().
> +**/
> +BOOLEAN
> +EFIAPI
> +UnitTestAssertNotEfiError (
> +  IN EFI_STATUS   Status,
> +  IN CONST CHAR8  *FunctionName,
> +  IN UINTN        LineNu= mber,
> +  IN CONST CHAR8  *FileName,
> +  IN CONST CHAR8  *Description
> +  );
> +
> +/**
> +  If ValueA is equal ValueB, then TRUE is returned.
> +  If ValueA is not equal to ValueB, then an assert is trigg= ered and the
> location
> +  of the assert provided by FunctionName, LineNumber, FileN= ame,
> DescriptionA,
> +  and DescriptionB are recorded and FALSE is returned.
> +
> +  @param[in]  ValueA     &nbs= p;  64-bit value.
> +  @param[in]  ValueB     &nbs= p;  64-bit value.
> +  @param[in]  FunctionName  Null-terminated ASCII= string of the function
> +          &nbs= p;            &= nbsp;    executing the assert macro.
> +  @param[in]  LineNumber    The source = file line number of the assert macro.
> +  @param[in]  FileName      N= ull-terminated ASCII string of the filename
> +          &nbs= p;            &= nbsp;    executing the assert macro.
> +  @param[in]  DescriptionA  Null-terminated ASCII= string that is a
> description
> +          &nbs= p;            &= nbsp;    of ValueA.
> +  @param[in]  DescriptionB  Null-terminated ASCII= string that is a
> description
> +          &nbs= p;            &= nbsp;    of ValueB.
> +
> +  @retval  TRUE   ValueA is equal to ValueB.=
> +  @retval  FALSE  ValueA is not equal to ValueB.<= br> > +**/
> +BOOLEAN
> +EFIAPI
> +UnitTestAssertEqual (
> +  IN UINT64       ValueA,
> +  IN UINT64       ValueB,
> +  IN CONST CHAR8  *FunctionName,
> +  IN UINTN        LineNu= mber,
> +  IN CONST CHAR8  *FileName,
> +  IN CONST CHAR8  *DescriptionA,
> +  IN CONST CHAR8  *DescriptionB
> +  );
> +
> +/**
> +  If the contents of BufferA are identical to the contents = of BufferB, then
> TRUE
> +  is returned.  If the contents of BufferA are not ide= ntical to the contents of
> +  BufferB, then an assert is triggered and the location of = the assert provided
> +  by FunctionName, LineNumber, FileName, DescriptionA, and = DescriptionB
> are
> +  recorded and FALSE is returned.
> +
> +  @param[in]  BufferA     &nb= sp; Pointer to a buffer for comparison.
> +  @param[in]  BufferB     &nb= sp; Pointer to a buffer for comparison.
> +  @param[in]  Length     &nbs= p;  Number of bytes to compare in BufferA and
> BufferB.
> +  @param[in]  FunctionName  Null-terminated ASCII= string of the function
> +          &nbs= p;            &= nbsp;    executing the assert macro.
> +  @param[in]  LineNumber    The source = file line number of the assert macro.
> +  @param[in]  FileName      N= ull-terminated ASCII string of the filename
> +          &nbs= p;            &= nbsp;    executing the assert macro.
> +  @param[in]  DescriptionA  Null-terminated ASCII= string that is a
> description
> +          &nbs= p;            &= nbsp;    of BufferA.
> +  @param[in]  DescriptionB  Null-terminated ASCII= string that is a
> description
> +          &nbs= p;            &= nbsp;    of BufferB.
> +
> +  @retval  TRUE   The contents of BufferA ar= e identical to the contents of
> +          &nbs= p;       BufferB.
> +  @retval  FALSE  The contents of BufferA are not= identical to the contents
> of
> +          &nbs= p;       BufferB.
> +**/
> +BOOLEAN
> +EFIAPI
> +UnitTestAssertMemEqual (
> +  IN VOID         *= BufferA,
> +  IN VOID         *= BufferB,
> +  IN UINTN        Length= ,
> +  IN CONST CHAR8  *FunctionName,
> +  IN UINTN        LineNu= mber,
> +  IN CONST CHAR8  *FileName,
> +  IN CONST CHAR8  *DescriptionA,
> +  IN CONST CHAR8  *DescriptionB
> +  );
> +
> +/**
> +  If ValueA is not equal ValueB, then TRUE is returned.
> +  If ValueA is equal to ValueB, then an assert is triggered= and the location
> +  of the assert provided by FunctionName, LineNumber, FileN= ame,
> DescriptionA
> +  and DescriptionB are recorded and FALSE is returned.
> +
> +  @param[in]  ValueA     &nbs= p;  64-bit value.
> +  @param[in]  ValueB     &nbs= p;  64-bit value.
> +  @param[in]  FunctionName  Null-terminated ASCII= string of the function
> +          &nbs= p;            &= nbsp;    executing the assert macro.
> +  @param[in]  LineNumber    The source = file line number of the assert macro.
> +  @param[in]  FileName      N= ull-terminated ASCII string of the filename
> +          &nbs= p;            &= nbsp;    executing the assert macro.
> +  @param[in]  DescriptionA  Null-terminated ASCII= string that is a
> description
> +          &nbs= p;            &= nbsp;    of ValueA.
> +  @param[in]  DescriptionB  Null-terminated ASCII= string that is a
> description
> +          &nbs= p;            &= nbsp;    of ValueB.
> +
> +  @retval  TRUE   ValueA is not equal to Val= ueB.
> +  @retval  FALSE  ValueA is equal to ValueB.
> +**/
> +BOOLEAN
> +EFIAPI
> +UnitTestAssertNotEqual (
> +  IN UINT64       ValueA,
> +  IN UINT64       ValueB,
> +  IN CONST CHAR8  *FunctionName,
> +  IN UINTN        LineNu= mber,
> +  IN CONST CHAR8  *FileName,
> +  IN CONST CHAR8  *DescriptionA,
> +  IN CONST CHAR8  *DescriptionB
> +  );
> +
> +/**
> +  If Status is equal to Expected, then TRUE is returned. > +  If Status is not equal to Expected, then an assert is tri= ggered and the
> +  location of the assert provided by FunctionName, LineNumb= er, FileName,
> and
> +  Description are recorded and FALSE is returned.
> +
> +  @param[in]  Status     &nbs= p;  EFI_STATUS value returned from an API under test.
> +  @param[in]  Expected      T= he expected EFI_STATUS return value from an
> API
> +          &nbs= p;            &= nbsp;    under test.
> +  @param[in]  FunctionName  Null-terminated ASCII= string of the function
> +          &nbs= p;            &= nbsp;    executing the assert macro.
> +  @param[in]  LineNumber    The source = file line number of the assert macro.
> +  @param[in]  FileName      N= ull-terminated ASCII string of the filename
> +          &nbs= p;            &= nbsp;    executing the assert macro.
> +  @param[in]  Description   Null-terminated = ASCII string that is a description
> +          &nbs= p;            &= nbsp;    of Status.
> +
> +  @retval  TRUE   Status is equal to Expecte= d.
> +  @retval  FALSE  Status is not equal to Expected= .
> +**/
> +BOOLEAN
> +EFIAPI
> +UnitTestAssertStatusEqual (
> +  IN EFI_STATUS   Status,
> +  IN EFI_STATUS   Expected,
> +  IN CONST CHAR8  *FunctionName,
> +  IN UINTN        LineNu= mber,
> +  IN CONST CHAR8  *FileName,
> +  IN CONST CHAR8  *Description
> +  );
> +
> +/**
> +  If Pointer is not equal to NULL, then TRUE is returned. > +  If Pointer is equal to NULL, then an assert is triggered = and the location of
> +  the assert provided by FunctionName, LineNumber, FileName= , and
> PointerName
> +  are recorded and FALSE is returned.
> +
> +  @param[in]  Pointer     &nb= sp; Pointer value to be checked against NULL.
> +  @param[in]  Expected      T= he expected EFI_STATUS return value from a
> function
> +          &nbs= p;            &= nbsp;    under test.
> +  @param[in]  FunctionName  Null-terminated ASCII= string of the function
> +          &nbs= p;            &= nbsp;    executing the assert macro.
> +  @param[in]  LineNumber    The source = file line number of the assert macro.
> +  @param[in]  FileName      N= ull-terminated ASCII string of the filename
> +          &nbs= p;            &= nbsp;    executing the assert macro.
> +  @param[in]  PointerName   Null-terminated = ASCII string that is a
> description
> +          &nbs= p;            &= nbsp;    of Pointer.
> +
> +  @retval  TRUE   Pointer is not equal to NU= LL.
> +  @retval  FALSE  Pointer is equal to NULL.
> +**/
> +BOOLEAN
> +EFIAPI
> +UnitTestAssertNotNull (
> +  IN VOID         *= Pointer,
> +  IN CONST CHAR8  *FunctionName,
> +  IN UINTN        LineNu= mber,
> +  IN CONST CHAR8  *FileName,
> +  IN CONST CHAR8  *PointerName
> +  );
> +
> +/**
> +  Test logging macro that records an ERROR message in the t= est framework
> log.
> +  Record is associated with the currently executing test ca= se.
> +
> +  @param[in]  Format  Formatting string following= the format defined in
> +          &nbs= p;           MdePkg/Inclu= de/Library/PrintLib.h.
> +  @param[in]  ...     Print args.<= br> > +**/
> +#define UT_LOG_ERROR(Format, ...)  \
> +  UnitTestLog (UNIT_TEST_LOG_LEVEL_ERROR, Format, ##__VA_AR= GS__)
> +
> +/**
> +  Test logging macro that records a WARNING message in the = test
> framework log.
> +  Record is associated with the currently executing test ca= se.
> +
> +  @param[in]  Format  Formatting string following= the format defined in
> +          &nbs= p;           MdePkg/Inclu= de/Library/PrintLib.h.
> +  @param[in]  ...     Print args.<= br> > +**/
> +#define UT_LOG_WARNING(Format, ...)  \
> +  UnitTestLog (UNIT_TEST_LOG_LEVEL_WARN, Format, ##__VA_ARG= S__)
> +
> +/**
> +  Test logging macro that records an INFO message in the te= st framework
> log.
> +  Record is associated with the currently executing test ca= se.
> +
> +  @param[in]  Format  Formatting string following= the format defined in
> +          &nbs= p;           MdePkg/Inclu= de/Library/PrintLib.h.
> +  @param[in]  ...     Print args.<= br> > +**/
> +#define UT_LOG_INFO(Format, ...)  \
> +  UnitTestLog (UNIT_TEST_LOG_LEVEL_INFO, Format, ##__VA_ARG= S__)
> +
> +/**
> +  Test logging macro that records a VERBOSE message in the = test
> framework log.
> +  Record is associated with the currently executing test ca= se.
> +
> +  @param[in]  Format  Formatting string following= the format defined in
> +          &nbs= p;           MdePkg/Inclu= de/Library/PrintLib.h.
> +  @param[in]  ...     Print args.<= br> > +**/
> +#define UT_LOG_VERBOSE(Format, ...)  \
> +  UnitTestLog (UNIT_TEST_LOG_LEVEL_VERBOSE, Format, ##__VA_= ARGS__)
> +
> +/**
> +  Test logging function that records a messages in the test= framework log.
> +  Record is associated with the currently executing test ca= se.
> +
> +  @param[in]  ErrorLevel  The error level of the = unit test log message.
> +  @param[in]  Format      For= matting string following the format defined in
> the
> +          &nbs= p;            &= nbsp;  MdePkg/Include/Library/PrintLib.h.
> +  @param[in]  ...      &= nbsp;  Print args.
> +**/
> +VOID
> +EFIAPI
> +UnitTestLog (
> +  IN  UINTN        = ErrorLevel,
> +  IN  CONST CHAR8  *Format,
> +  ...
> +  );
> +
> +#endif
> diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
> index d022cc5e3e..ac1f5339af 100644
> --- a/MdePkg/MdePkg.dec
> +++ b/MdePkg/MdePkg.dec
> @@ -244,6 +244,10 @@ [LibraryClasses]
>    ##  @libraryclass  Module entry point lib= rary for standalone MM drivers.
>
> StandaloneMmDriverEntryPoint|Include/Library/StandaloneMmDriverEntryP=
> oint.h
>
> +  ## @libraryclass Provides a unit test framework
> +  #
> +  UnitTestLib|Include/Library/UnitTestLib.h
> +
>  [LibraryClasses.IA32, LibraryClasses.X64]
>    ##  @libraryclass  Abstracts both S/W SMI= generation and detection.
>    ##
> --
> 2.21.0.windows.1
>
>
>

--_000_CY4PR21MB0743F68EE69A56DD7F0C6F5FEF1C0CY4PR21MB0743namp_--