[edk2-devel] [PATCH v2 10/12] MdeModulePkg: Add a shell-based functional test for VariablePolicy

Michael Kubacki michael.kubacki at outlook.com
Tue May 12 06:46:33 UTC 2020


From: Bret Barkelew <brbarkel at microsoft.com>

https://bugzilla.tianocore.org/show_bug.cgi?id=2522

To verify that VariablePolicy is correctly integrated
on platforms, add a Shell-based functional test to
confirm expected behavior.

NOTE: This test assumes that VariablePolicy is built
with PcdAllowVariablePolicyEnforcementDisable set to
TRUE.

Cc: Jian J Wang <jian.j.wang at intel.com>
Cc: Hao A Wu <hao.a.wu at intel.com>
Cc: Liming Gao <liming.gao at intel.com>
Signed-off-by: Michael Kubacki <michael.kubacki at microsoft.com>
---
 MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.c   | 1942 ++++++++++++++++++++
 MdeModulePkg/MdeModulePkg.ci.yaml                                                   |    4 +-
 MdeModulePkg/MdeModulePkg.dsc                                                       |    6 +
 MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md                     |   55 +
 MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.inf |   42 +
 5 files changed, 2048 insertions(+), 1 deletion(-)

diff --git a/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.c b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.c
new file mode 100644
index 000000000000..736d5a27d8ae
--- /dev/null
+++ b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.c
@@ -0,0 +1,1942 @@
+/**
+ at file
+UEFI Shell based application for unit testing the Variable Policy Protocol.
+
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/UefiLib.h>
+#include <Library/PrintLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UnitTestLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/VariablePolicy.h>
+#include <Library/VariablePolicyHelperLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+// TODO: Need to add to the UnitTestFrameworkPkg
+// #include <Library/UnitTestBootLib.h>
+
+#define UNIT_TEST_APP_NAME        "Variable Policy Unit Test Application"
+#define UNIT_TEST_APP_VERSION     "0.1"
+
+// TODO: Need to add to the UnitTestFrameworkPkg
+UNIT_TEST_FRAMEWORK_HANDLE
+GetActiveFrameworkHandle (
+  VOID
+  );
+
+VARIABLE_POLICY_PROTOCOL  *mVarPol = NULL;
+
+
+EFI_GUID mTestNamespaceGuid1 = { 0x3b389299, 0xabaf, 0x433b, { 0xa4, 0xa9, 0x23, 0xc8, 0x44, 0x02, 0xfc, 0xad } };
+EFI_GUID mTestNamespaceGuid2 = { 0x4c49a3aa, 0xbcb0, 0x544c, { 0xb5, 0xba, 0x34, 0xd9, 0x55, 0x13, 0x0d, 0xbe } };
+EFI_GUID mTestNamespaceGuid3 = { 0x5d5ab4bb, 0xcdc1, 0x655d, { 0xc6, 0xcb, 0x45, 0xea, 0x66, 0x24, 0x1e, 0xcf } };
+
+//
+// Pre-req
+//
+UNIT_TEST_STATUS
+EFIAPI
+LocateVarPolicyPreReq (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+
+  if (mVarPol == NULL) {
+    Status = gBS->LocateProtocol (&gVariablePolicyProtocolGuid,
+                                  NULL,
+                                  (VOID **) &mVarPol);
+    UT_ASSERT_NOT_EFI_ERROR (Status);
+    UT_ASSERT_NOT_NULL (mVarPol);
+  }
+
+  return UNIT_TEST_PASSED;
+
+} // LocateVarPolicyPreReq
+
+//
+// Getting Started tests:
+//
+UNIT_TEST_STATUS
+CheckVpEnabled (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+  BOOLEAN State;
+
+  Status = mVarPol->IsVariablePolicyEnabled (&State);
+
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (State, TRUE);
+
+  return UNIT_TEST_PASSED;
+} // CheckVpEnabled
+
+UNIT_TEST_STATUS
+CheckVpRevision (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  UT_ASSERT_NOT_EQUAL (mVarPol->Revision, 0);
+  UT_LOG_INFO ("VP Revision: 0x%x\n", mVarPol->Revision);
+
+  return UNIT_TEST_PASSED;
+} // CheckVpRevision
+
+//
+// NoLock Policy tests:
+//
+UNIT_TEST_STATUS
+TestMinSizeNoLock (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+  UINT8      Value1;
+  UINT32     Value2;
+  UINT8     *Buffer;
+
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"MinSizeNoLockVar",
+                                        4,
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        VARIABLE_POLICY_NO_MUST_ATTR,
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        VARIABLE_POLICY_TYPE_NO_LOCK);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Try to write a var that is smaller than minsize
+  //
+  Value1 = 0x12;
+  Status = gRT->SetVariable (L"MinSizeNoLockVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+                             sizeof (Value1),
+                             &Value1);
+  UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER));
+
+  //
+  // Try to write a var of size that matches minsize
+  //
+  Value2 = 0xa1b2c3d4;
+  Status = gRT->SetVariable (L"MinSizeNoLockVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+                             sizeof (Value2),
+                             &Value2);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Should be able to delete the var
+  //
+  Status = gRT->SetVariable (L"MinSizeNoLockVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Try to write a var of size larger than minsize
+  //
+  Buffer = AllocateZeroPool (40);
+  UT_ASSERT_NOT_NULL (Buffer);
+  Status = gRT->SetVariable (L"MinSizeNoLockVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+                             40,
+                             Buffer);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Delete the variable
+  //
+  Status = gRT->SetVariable (L"MinSizeNoLockVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  FreePool (Buffer);
+
+  return UNIT_TEST_PASSED;
+} // TestMinSizeNoLock
+
+UNIT_TEST_STATUS
+TestMaxSizeNoLock (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+  UINT8      Value1;
+  UINT32     Value2;
+  UINT8     *Buffer;
+
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"MaxSizeNoLockVar",
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        4,
+                                        VARIABLE_POLICY_NO_MUST_ATTR,
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        VARIABLE_POLICY_TYPE_NO_LOCK);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Try to write a var that is smaller than maxsize
+  //
+  Value1 = 0x34;
+  Status = gRT->SetVariable (L"MaxSizeNoLockVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+                             sizeof (Value1),
+                             &Value1);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Should be able to delete the var
+  //
+  Status = gRT->SetVariable (L"MaxSizeNoLockVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Try to write a var of size that matches maxsize
+  //
+  Value2 = 0xa1b2c3d4;
+  Status = gRT->SetVariable (L"MaxSizeNoLockVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+                             sizeof (Value2),
+                             &Value2);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Should be able to delete the var
+  //
+  Status = gRT->SetVariable (L"MaxSizeNoLockVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Try to write a var of size larger than maxsize
+  //
+  Buffer = AllocateZeroPool (40);
+  UT_ASSERT_NOT_NULL (Buffer);
+  Status = gRT->SetVariable (L"MaxSizeNoLockVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+                             40,
+                             Buffer);
+  UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER));
+
+  FreePool (Buffer);
+
+  return UNIT_TEST_PASSED;
+} // TestMaxSizeNoLock
+
+UNIT_TEST_STATUS
+TestMustHaveAttrNoLock (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+  UINT8      Value;
+
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"MustHaveAttrNoLockVar",
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        VARIABLE_POLICY_TYPE_NO_LOCK);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Try to write a var that doesn't have the must-have attributes
+  //
+  Value = 0x56;
+  Status = gRT->SetVariable (L"MustHaveAttrNoLockVar",
+                             &mTestNamespaceGuid1,
+                             EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER));
+
+  //
+  // Try to write a var that has exactly the required attributes
+  //
+  Status = gRT->SetVariable (L"MustHaveAttrNoLockVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Should be able to delete the var
+  // NOTE: some implementations of VP will require the musthave attributes to be passed even when deleting
+  //
+  Status = gRT->SetVariable (L"MustHaveAttrNoLockVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Try to write a var that has the required attributes and one extra attribute
+  //
+  Status = gRT->SetVariable (L"MustHaveAttrNoLockVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Should be able to delete the var
+  // NOTE: some implementations of VP will require the musthave attributes to be passed even when deleting
+  //
+  Status = gRT->SetVariable (L"MustHaveAttrNoLockVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  return UNIT_TEST_PASSED;
+} // TestMustHaveAttrNoLock
+
+UNIT_TEST_STATUS
+TestCantHaveAttrNoLock (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+  UINT8      Value;
+
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"CantHaveAttrNoLockVar",
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        VARIABLE_POLICY_NO_MUST_ATTR,
+                                        EFI_VARIABLE_NON_VOLATILE,
+                                        VARIABLE_POLICY_TYPE_NO_LOCK);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Try to write a var that has a can't have attr
+  //
+  Value = 0x78;
+  Status = gRT->SetVariable (L"CantHaveAttrNoLockVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER));
+
+  //
+  // Try to write a var that satisfies the can't have requirement
+  //
+  Status = gRT->SetVariable (L"CantHaveAttrNoLockVar",
+                             &mTestNamespaceGuid1,
+                             EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Should be able to delete the var
+  //
+  Status = gRT->SetVariable (L"CantHaveAttrNoLockVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  return UNIT_TEST_PASSED;
+} // TestCantHaveAttrNoLock
+
+UNIT_TEST_STATUS
+TestMaxSizeNamespaceNoLock (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+  UINT8      Value1;
+  UINT32     Value2;
+  UINT8     *Buffer;
+
+  //
+  // Register a namespace-wide policy limiting max size to 4 bytes
+  //
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid2,
+                                        NULL,
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        4,
+                                        VARIABLE_POLICY_NO_MUST_ATTR,
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        VARIABLE_POLICY_TYPE_NO_LOCK);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Try to write a var that is smaller than maxsize
+  //
+  Value1 = 0x34;
+  Status = gRT->SetVariable (L"MaxSizeNoLockVar",
+                             &mTestNamespaceGuid2,
+                             (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+                             sizeof (Value1),
+                             &Value1);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Should be able to delete the var
+  //
+  Status = gRT->SetVariable (L"MaxSizeNoLockVar",
+                             &mTestNamespaceGuid2,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Try to write a var of size that matches maxsize
+  //
+  Value2 = 0xa1b2c3d4;
+  Status = gRT->SetVariable (L"MaxSizeNoLockVar",
+                             &mTestNamespaceGuid2,
+                             (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+                             sizeof (Value2),
+                             &Value2);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Should be able to delete the var
+  //
+  Status = gRT->SetVariable (L"MaxSizeNoLockVar",
+                             &mTestNamespaceGuid2,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Try to write a var of size larger than maxsize
+  //
+  Buffer = AllocateZeroPool (40);
+  UT_ASSERT_NOT_NULL (Buffer);
+  Status = gRT->SetVariable (L"MaxSizeNoLockVar",
+                             &mTestNamespaceGuid2,
+                             (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+                             40,
+                             Buffer);
+  UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER));
+
+  FreePool (Buffer);
+
+  return UNIT_TEST_PASSED;
+} // TestMaxSizeNamespaceNoLock
+
+UNIT_TEST_STATUS
+TestMustHaveAttrWildcardNoLock (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+  UINT8      Value;
+
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"MustHaveAttrWildcardNoLockVar####",
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        VARIABLE_POLICY_TYPE_NO_LOCK);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Try to write a var that doesn't have the must-have attributes
+  //
+  Value = 0x56;
+  Status = gRT->SetVariable (L"MustHaveAttrWildcardNoLockVar1573",
+                             &mTestNamespaceGuid1,
+                             EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER));
+
+  //
+  // Try to write a var that has exactly the required attributes
+  //
+  Status = gRT->SetVariable (L"MustHaveAttrWildcardNoLockVar1234",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Should be able to delete the var
+  // NOTE: some implementations of VP will require the musthave attributes to be passed even when deleting
+  //
+  Status = gRT->SetVariable (L"MustHaveAttrWildcardNoLockVar1234",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Try to write a var that has the required attributes and one extra attribute
+  //
+  Status = gRT->SetVariable (L"MustHaveAttrWildcardNoLockVar5612",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Should be able to delete the var
+  // NOTE: some implementations of VP will require the musthave attributes to be passed even when deleting
+  //
+  Status = gRT->SetVariable (L"MustHaveAttrWildcardNoLockVar5612",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  return UNIT_TEST_PASSED;
+} // TestMustHaveAttrWildcardNoLock
+
+UNIT_TEST_STATUS
+TestPolicyprioritizationNoLock (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+  UINT8      Value8;
+  UINT16     Value16;
+  UINT32     Value32;
+  UINT64     Value64;
+
+  //
+  // Register a policy targeting the specific var
+  //
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid3,
+                                        L"PolicyPriorityTestVar123",
+                                        8, // min size of UINT64
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        VARIABLE_POLICY_NO_MUST_ATTR,
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        VARIABLE_POLICY_TYPE_NO_LOCK);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Register a policy with wildcards in the name
+  //
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid3,
+                                        L"PolicyPriorityTestVar###",
+                                        4, // min size of UINT32
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        VARIABLE_POLICY_NO_MUST_ATTR,
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        VARIABLE_POLICY_TYPE_NO_LOCK);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Register a policy with wildcards in the name
+  //
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid3,
+                                        NULL,
+                                        2, // min size of UINT16
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        VARIABLE_POLICY_NO_MUST_ATTR,
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        VARIABLE_POLICY_TYPE_NO_LOCK);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // The idea is that the most specific policy is applied:
+  //   For varname "TestVar", the namespace-wide one should apply: UINT16 minimum
+  //   For varname "PolicyPriorityTestVar567" the wildcard policy should apply: UINT32 minimum
+  //   For varname "PolicyPriorityTestVar123" the var-specific policy should apply: UINT64 minimum
+  //
+
+  //
+  // Let's confirm the namespace-wide policy enforcement
+  //
+  Value8 = 0x78;
+  Status = gRT->SetVariable (L"TestVar",
+                             &mTestNamespaceGuid3,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value8),
+                             &Value8);
+  UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER));
+
+  Value16 = 0x6543;
+  Status = gRT->SetVariable (L"TestVar",
+                             &mTestNamespaceGuid3,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value16),
+                             &Value16);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Let's confirm the wildcard policy enforcement
+  //
+  Value16 = 0xabba;
+  Status = gRT->SetVariable (L"PolicyPriorityTestVar567",
+                             &mTestNamespaceGuid3,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value16),
+                             &Value16);
+  UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER));
+
+  Value32 = 0xfedcba98;
+  Status = gRT->SetVariable (L"PolicyPriorityTestVar567",
+                             &mTestNamespaceGuid3,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value32),
+                             &Value32);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Let's confirm the var-specific policy enforcement
+  //
+  Value32 = 0x8d3f627c;
+  Status = gRT->SetVariable (L"PolicyPriorityTestVar123",
+                             &mTestNamespaceGuid3,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value32),
+                             &Value32);
+  UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER));
+
+  Value64 = 0xbebecdcdafaf6767;
+  Status = gRT->SetVariable (L"PolicyPriorityTestVar123",
+                             &mTestNamespaceGuid3,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value64),
+                             &Value64);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  return UNIT_TEST_PASSED;
+} // TestPolicyprioritizationNoLock
+
+//
+// LockNow Policy tests:
+//
+UNIT_TEST_STATUS
+TestExistingVarLockNow (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+  UINT8      Value;
+
+  //
+  // Write a var that we'll protect next
+  //
+  Value = 0x78;
+  Status = gRT->SetVariable (L"ExistingLockNowVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Register a LockNow policy targeting the var
+  //
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"ExistingLockNowVar",
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        VARIABLE_POLICY_NO_MUST_ATTR,
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        VARIABLE_POLICY_TYPE_LOCK_NOW);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Attempt to modify the locked var
+  //
+  Value = 0xA5;
+  Status = gRT->SetVariable (L"ExistingLockNowVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);
+
+  //
+  // Attempt to delete the locked var
+  //
+  Status = gRT->SetVariable (L"ExistingLockNowVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);
+
+  //
+  // This variable is deleted in final cleanup.
+  //
+
+  return UNIT_TEST_PASSED;
+} // TestExistingVarLockNow
+
+UNIT_TEST_STATUS
+TestNonexistentVarLockNow (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+  UINT8      Value;
+  UINTN      Size;
+
+  //
+  // Make sure the variable we're about to create the policy for doesn't exist
+  //
+  Size = 0;
+  Status = gRT->GetVariable (L"NonexistentLockNowVar",
+                             &mTestNamespaceGuid1,
+                             NULL,
+                             &Size,
+                             NULL);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND);
+
+  //
+  // Register a LockNow policy targeting the var
+  //
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"NonexistentLockNowVar",
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        VARIABLE_POLICY_NO_MUST_ATTR,
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        VARIABLE_POLICY_TYPE_LOCK_NOW);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Attempt to create the locked var
+  //
+  Value = 0xA5;
+  Status = gRT->SetVariable (L"NonexistentLockNowVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);
+
+  return UNIT_TEST_PASSED;
+} // TestNonexistentVarLockNow
+
+//
+// LockOnCreate Policy tests:
+//
+UNIT_TEST_STATUS
+TestExistingVarLockOnCreate (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+  UINT8      Value;
+
+  //
+  // Write a var that we'll protect later
+  //
+  Value = 0x78;
+  Status = gRT->SetVariable (L"ExistingLockOnCreateVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Register a LockNow policy targeting the var
+  //
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"ExistingLockOnCreateVar",
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        VARIABLE_POLICY_NO_MUST_ATTR,
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        VARIABLE_POLICY_TYPE_LOCK_ON_CREATE);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Attempt to modify the locked var
+  //
+  Value = 0xA5;
+  Status = gRT->SetVariable (L"ExistingLockOnCreateVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);
+
+  //
+  // Attempt to delete the locked var
+  //
+  Status = gRT->SetVariable (L"ExistingLockOnCreateVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);
+
+  //
+  // This variable is deleted in final cleanup.
+  //
+
+  return UNIT_TEST_PASSED;
+} // TestExistingVarLockOnCreate
+
+UNIT_TEST_STATUS
+TestNonexistentVarLockOnCreate (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+  UINT8      Value1;
+  UINT32     Value2;
+  UINTN      Size;
+
+  //
+  // Make sure the variable we're about to create the policy for doesn't exist
+  //
+  Size = 0;
+  Status = gRT->GetVariable (L"NonexistentLockOnCreateVar",
+                             &mTestNamespaceGuid1,
+                             NULL,
+                             &Size,
+                             NULL);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND);
+
+  //
+  // Register a LockOnCreate policy targeting the var
+  //
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"NonexistentLockOnCreateVar",
+                                        2, // min size of 2 bytes, UINT16+
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        EFI_VARIABLE_RUNTIME_ACCESS, // must have RT attr
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        VARIABLE_POLICY_TYPE_LOCK_ON_CREATE);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Attempt to create the var, but smaller than min size
+  //
+  Value1 = 0xA5;
+  Status = gRT->SetVariable (L"NonexistentLockOnCreateVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value1),
+                             &Value1);
+  UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER));
+
+  //
+  // Now let's make sure attribute req is enforced
+  //
+  Value2 = 0x43218765;
+  Status = gRT->SetVariable (L"NonexistentLockOnCreateVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value2),
+                             &Value2);
+  UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER));
+
+  //
+  // Now let's create a valid variable
+  //
+  Value2 = 0x43218765;
+  Status = gRT->SetVariable (L"NonexistentLockOnCreateVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value2),
+                             &Value2);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Let's make sure we can't modify it
+  //
+  Value2 = 0xa5a5b6b6;
+  Status = gRT->SetVariable (L"NonexistentLockOnCreateVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value2),
+                             &Value2);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);
+
+  //
+  // Finally, let's make sure we can't delete it
+  //
+  Status = gRT->SetVariable (L"NonexistentLockOnCreateVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);
+
+  //
+  // This variable is deleted in final cleanup.
+  //
+
+  return UNIT_TEST_PASSED;
+} // TestNonexistentVarLockOnCreate
+
+//
+// LockOnVarState Policy tests:
+//
+UNIT_TEST_STATUS
+TestLockOnVarStateBeforeCreate (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+  UINTN      Size;
+  UINT8      Value;
+
+  //
+  // First of all, let's make sure the var we're trying to protect doesn't exist
+  //
+  Size = 0;
+  Status = gRT->GetVariable (L"NonexistentLockOnVarStateVar",
+                             &mTestNamespaceGuid1,
+                             NULL,
+                             &Size,
+                             NULL);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND);
+
+  //
+  // Good, now let's create a policy
+  //
+  Status = RegisterVarStateVariablePolicy (mVarPol,
+                                           &mTestNamespaceGuid1,
+                                           L"NonexistentLockOnVarStateVar",
+                                           VARIABLE_POLICY_NO_MIN_SIZE,
+                                           VARIABLE_POLICY_NO_MAX_SIZE,
+                                           VARIABLE_POLICY_NO_MUST_ATTR,
+                                           VARIABLE_POLICY_NO_CANT_ATTR,
+                                           &mTestNamespaceGuid1,
+                                           L"Trigger1",
+                                           0x7E);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Now we write the trigger var
+  //
+  Value = 0x7E;
+  Status = gRT->SetVariable (L"Trigger1",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Ok, now we attempt to write a var protected by the trigger
+  //
+  Value = 0xFA;
+  Status = gRT->SetVariable (L"NonexistentLockOnVarStateVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);
+
+  //
+  // Let's modify the trigger var and "untrigger" the policy
+  //
+  Value = 0x38;
+  Status = gRT->SetVariable (L"Trigger1",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Now we should be able to create the var targeted by the policy
+  //
+  Value = 0x23;
+  Status = gRT->SetVariable (L"NonexistentLockOnVarStateVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Cleanup: delete the trigger and the protected var
+  //
+  Status = gRT->SetVariable (L"Trigger1",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  Status = gRT->SetVariable (L"NonexistentLockOnVarStateVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  return UNIT_TEST_PASSED;
+} // TestLockOnVarStateBeforeCreate
+
+UNIT_TEST_STATUS
+TestLockOnVarStateAfterCreate (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+  UINT8      Value;
+
+  //
+  // Let's create a policy
+  //
+  Status = RegisterVarStateVariablePolicy (mVarPol,
+                                           &mTestNamespaceGuid1,
+                                           L"ExistingLockOnVarStateVar",
+                                           VARIABLE_POLICY_NO_MIN_SIZE,
+                                           VARIABLE_POLICY_NO_MAX_SIZE,
+                                           VARIABLE_POLICY_NO_MUST_ATTR,
+                                           VARIABLE_POLICY_NO_CANT_ATTR,
+                                           &mTestNamespaceGuid1,
+                                           L"Trigger2",
+                                           0x5C);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Should be able to write targeted var since the policy isn't active yet.
+  //
+  Value = 0x17;
+  Status = gRT->SetVariable (L"ExistingLockOnVarStateVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Let's modify the var to make sure the policy isn't acting like a lock-on-create one
+  //
+  Value = 0x30;
+  Status = gRT->SetVariable (L"ExistingLockOnVarStateVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Now we trigger the policy
+  //
+  Value = 0x5C;
+  Status = gRT->SetVariable (L"Trigger2",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Let's now verify the variable is protected
+  //
+  Value = 0xB9;
+  Status = gRT->SetVariable (L"ExistingLockOnVarStateVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);
+
+  //
+  // Ok, to clean up, we need to remove the trigger var, so delete it, and then delete the target var
+  //
+  Status = gRT->SetVariable (L"Trigger2",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  Status = gRT->SetVariable (L"ExistingLockOnVarStateVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  return UNIT_TEST_PASSED;
+} // TestLockOnVarStateAfterCreate
+
+UNIT_TEST_STATUS
+TestLockOnVarStateInvalidLargeTrigger (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+  UINT16     Value;
+
+  //
+  // First let's create a variable policy
+  //
+  Status = RegisterVarStateVariablePolicy (mVarPol,
+                                           &mTestNamespaceGuid1,
+                                           L"InvalidLargeTriggerLockOnVarStateVar",
+                                           VARIABLE_POLICY_NO_MIN_SIZE,
+                                           VARIABLE_POLICY_NO_MAX_SIZE,
+                                           VARIABLE_POLICY_NO_MUST_ATTR,
+                                           VARIABLE_POLICY_NO_CANT_ATTR,
+                                           &mTestNamespaceGuid1,
+                                           L"Trigger3",
+                                           0x5C);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Now attempt to trigger the lock but with a variable larger than one byte
+  //
+  Value = 0x8085;
+  Status = gRT->SetVariable (L"Trigger3",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Should still be able to create the targeted var
+  //
+  Value = 0x1234;
+  Status = gRT->SetVariable (L"InvalidLargeTriggerLockOnVarStateVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Let's clean up by deleting the invalid trigger and the targeted var
+  //
+  Status = gRT->SetVariable (L"Trigger3",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  Status = gRT->SetVariable (L"InvalidLargeTriggerLockOnVarStateVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  return UNIT_TEST_PASSED;
+} // TestLockOnVarStateInvalidLargeTrigger
+
+UNIT_TEST_STATUS
+TestLockOnVarStateWrongValueTrigger (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+  UINT8      Value;
+
+  //
+  // First let's create a variable policy
+  //
+  Status = RegisterVarStateVariablePolicy (mVarPol,
+                                           &mTestNamespaceGuid1,
+                                           L"WrongValueTriggerLockOnVarStateVar",
+                                           VARIABLE_POLICY_NO_MIN_SIZE,
+                                           VARIABLE_POLICY_NO_MAX_SIZE,
+                                           VARIABLE_POLICY_NO_MUST_ATTR,
+                                           VARIABLE_POLICY_NO_CANT_ATTR,
+                                           &mTestNamespaceGuid1,
+                                           L"Trigger4",
+                                           0xCA);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Now attempt to trigger the lock but with a wrong value
+  //
+  Value = 0x80;
+  Status = gRT->SetVariable (L"Trigger4",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Should still be able to create the targeted var
+  //
+  Value = 0x14;
+  Status = gRT->SetVariable (L"WrongValueTriggerLockOnVarStateVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Let's clean up by deleting the invalid trigger and the targeted var
+  //
+  Status = gRT->SetVariable (L"Trigger4",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  Status = gRT->SetVariable (L"WrongValueTriggerLockOnVarStateVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  return UNIT_TEST_PASSED;
+} // TestLockOnVarStateWrongValueTrigger
+
+//
+// Invalid policy tests:
+//
+UNIT_TEST_STATUS
+TestInvalidAttributesPolicy (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+
+  //
+  // The only must/can't have attributes supported by VPE are NV, BS, and RT. They are 1, 2, and 4, respectively.
+  // Let's try some bits higher than that?
+  //
+
+  //
+  // Trying must have attribute 0x8 which is EFI_VARIABLE_HARDWARE_ERROR_RECORD
+  //
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"InvalidMustHaveAttributesPolicyVar1",
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        EFI_VARIABLE_HARDWARE_ERROR_RECORD,
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        VARIABLE_POLICY_TYPE_NO_LOCK);
+  UT_LOG_INFO ("Setting must have attr to EFI_VARIABLE_HARDWARE_ERROR_RECORD returned %r\n", Status);
+
+  //
+  // Let's try 0x10 - EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, a deprecated attribute
+  //
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"InvalidMustHaveAttributesPolicyVar2",
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        VARIABLE_POLICY_TYPE_NO_LOCK);
+  UT_LOG_INFO ("Setting must have attr to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS returned %r\n", Status);
+
+  //
+  // Let's try 0x20 - EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
+  //
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"InvalidMustHaveAttributesPolicyVar3",
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        VARIABLE_POLICY_TYPE_NO_LOCK);
+  UT_LOG_INFO ("Setting must have attr to EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS returned %r\n", Status);
+
+  //
+  // Let's try something wild, like 0x4000
+  //
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"InvalidMustHaveAttributesPolicyVar4",
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        0x4000,
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        VARIABLE_POLICY_TYPE_NO_LOCK);
+  UT_LOG_INFO ("Setting must have attr to 0x4000 returned %r\n", Status);
+
+  //
+  // Now repeat the same tests, but for the can't-have param
+  //
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"InvalidCantHaveAttributesPolicyVar1",
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        VARIABLE_POLICY_NO_MUST_ATTR,
+                                        EFI_VARIABLE_HARDWARE_ERROR_RECORD,
+                                        VARIABLE_POLICY_TYPE_NO_LOCK);
+  UT_LOG_INFO ("Setting cant have attr to EFI_VARIABLE_HARDWARE_ERROR_RECORD returned %r\n", Status);
+
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"InvalidCantHaveAttributesPolicyVar2",
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        VARIABLE_POLICY_NO_MUST_ATTR,
+                                        EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,
+                                        VARIABLE_POLICY_TYPE_NO_LOCK);
+  UT_LOG_INFO ("Setting cant have attr to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS returned %r\n", Status);
+
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"InvalidCantHaveAttributesPolicyVar3",
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        VARIABLE_POLICY_NO_MUST_ATTR,
+                                        EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,
+                                        VARIABLE_POLICY_TYPE_NO_LOCK);
+  UT_LOG_INFO ("Setting cant have attr to EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS returned %r\n", Status);
+
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"InvalidCantHaveAttributesPolicyVar4",
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        VARIABLE_POLICY_NO_MUST_ATTR,
+                                        0x4000,
+                                        VARIABLE_POLICY_TYPE_NO_LOCK);
+  UT_LOG_INFO ("Setting cant have attr to 0x4000 returned %r\n", Status);
+
+  return UNIT_TEST_PASSED;
+} // TestInvalidAttributesPolicy
+
+UNIT_TEST_STATUS
+TestLargeMinSizePolicy (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+
+  //
+  // Let's set the min size to 2GB and see what happens
+  //
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"LargeMinSizeInvalidPolicyVar",
+                                        0x80000000,
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        VARIABLE_POLICY_NO_MUST_ATTR,
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        VARIABLE_POLICY_TYPE_NO_LOCK);
+
+  UT_LOG_INFO ("Setting min size to 0x80000000 returned %r\n", Status);
+
+  return UNIT_TEST_PASSED;
+} // TestLargeMinSizePolicy
+
+UNIT_TEST_STATUS
+TestZeroMaxSizePolicy (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+
+  //
+  // Let's set the max size to 0 and see what happens
+  //
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"ZeroMinSizeInvalidPolicyVar",
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        0,
+                                        VARIABLE_POLICY_NO_MUST_ATTR,
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        VARIABLE_POLICY_TYPE_NO_LOCK);
+  //UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS); // this fails on QC. Real bug? Do we care?
+  UT_LOG_INFO ("Setting max size to 0 returned %r\n", Status);
+
+  return UNIT_TEST_PASSED;
+} // TestZeroMaxSizePolicy
+
+UNIT_TEST_STATUS
+TestInvalidPolicyTypePolicy (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+
+  //
+  // Let's set policy type to an invalid value and see what happens
+  // Valid ones are:
+  //        VARIABLE_POLICY_TYPE_NO_LOCK            0
+  //        VARIABLE_POLICY_TYPE_LOCK_NOW           1
+  //        VARIABLE_POLICY_TYPE_LOCK_ON_CREATE     2
+  //        VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE  3
+  //
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"InvalidPolicyTypePolicyVar",
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        VARIABLE_POLICY_NO_MUST_ATTR,
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        4);
+  UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS);
+
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"InvalidPolicyTypePolicyVar",
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        VARIABLE_POLICY_NO_MUST_ATTR,
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        147);
+  UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS);
+
+  return UNIT_TEST_PASSED;
+} // TestInvalidPolicyTypePolicy
+
+//
+// Test dumping policy:
+//
+UNIT_TEST_STATUS
+TestDumpPolicy (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+  UINT8*     Buffer;
+  UINT32     Size;
+
+  //
+  // First let's call DumpVariablePolicy with null buffer to get size
+  //
+  Size = 0;
+  Status = mVarPol->DumpVariablePolicy (NULL, &Size);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_BUFFER_TOO_SMALL);
+
+  //
+  // Now we allocate the buffer for the dump
+  //
+  Buffer = NULL;
+  Buffer = AllocatePool (Size);
+  UT_ASSERT_NOT_NULL (Buffer);
+
+  //
+  // Now we get the dump. In this test we will not analyze the dump.
+  //
+  Status = mVarPol->DumpVariablePolicy (Buffer, &Size);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  return UNIT_TEST_PASSED;
+} // TestDumpPolicy
+
+//
+// Test policy version:
+//
+UNIT_TEST_STATUS
+TestPolicyVersion (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS             Status;
+  VARIABLE_POLICY_ENTRY  *NewEntry;
+
+  //
+  // Create the new entry using a helper lib
+  //
+  NewEntry = NULL;
+  Status = CreateBasicVariablePolicy (&mTestNamespaceGuid1,
+                                      L"PolicyVersionTestNoLockVar",
+                                      VARIABLE_POLICY_NO_MIN_SIZE,
+                                      4, // max size of 4 bytes
+                                      VARIABLE_POLICY_NO_MUST_ATTR,
+                                      VARIABLE_POLICY_NO_CANT_ATTR,
+                                      VARIABLE_POLICY_TYPE_NO_LOCK,
+                                      &NewEntry);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  NewEntry->Version = 0x1234;
+  Status = mVarPol->RegisterVariablePolicy (NewEntry);
+  UT_LOG_INFO ("Registering policy entry with an unknown version status: %r\n", Status);
+
+  FreePool (NewEntry);
+
+  return UNIT_TEST_PASSED;
+} // TestPolicyVersion
+
+//
+// Lock Policy Tests:
+//
+UNIT_TEST_STATUS
+LockPolicyEngineTests (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS  Status;
+  UINT16      Value;
+  UINT64      Value64;
+  BOOLEAN     State;
+
+  //
+  // First let's register a policy that we'll test after VPE lock
+  //
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"BeforeVpeLockNoLockPolicyVar",
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        4, // max size of 4 bytes
+                                        VARIABLE_POLICY_NO_MUST_ATTR,
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        VARIABLE_POLICY_TYPE_LOCK_ON_CREATE);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Now, lock VPE!
+  //
+  Status = mVarPol->LockVariablePolicy ();
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // See if we can lock it again?
+  //
+  Status = mVarPol->LockVariablePolicy ();
+  UT_LOG_INFO ("Locking VPE for second time returned %r\n", Status);
+
+  //
+  // Let's confirm one of the policies from prior test suites is still enforced
+  // Attempt to delete a locked var
+  //
+  Status = gRT->SetVariable (L"ExistingLockNowVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);
+
+  //
+  // We'll make sure the policy from earlier in this test case is actively filtering out by size
+  //
+  Value64 = 0x3829fed212345678;
+  Status = gRT->SetVariable (L"BeforeVpeLockNoLockPolicyVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+                             sizeof (Value64),
+                             &Value64);
+  UT_ASSERT_TRUE ((Status == EFI_WRITE_PROTECTED) || (Status == EFI_INVALID_PARAMETER));
+
+  //
+  // Let's create the variable from the policy now
+  //
+  Value = 0x323f;
+  Status = gRT->SetVariable (L"BeforeVpeLockNoLockPolicyVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Now confirm that the var is locked after creation
+  //
+  Value = 0x1212;
+  Status = gRT->SetVariable (L"BeforeVpeLockNoLockPolicyVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);
+
+  //
+  // Let's attempt to register a new policy, it should fail
+  //
+  Status = RegisterBasicVariablePolicy (mVarPol,
+                                        &mTestNamespaceGuid1,
+                                        L"AfterVpeLockNowPolicyVar",
+                                        VARIABLE_POLICY_NO_MIN_SIZE,
+                                        VARIABLE_POLICY_NO_MAX_SIZE,
+                                        VARIABLE_POLICY_NO_MUST_ATTR,
+                                        VARIABLE_POLICY_NO_CANT_ATTR,
+                                        VARIABLE_POLICY_TYPE_LOCK_NOW);
+  UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS);
+
+  //
+  // Make sure VPE is enabled
+  //
+  Status = mVarPol->IsVariablePolicyEnabled (&State);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (State, TRUE);
+
+  //
+  // Finally, make sure we can't disable VPE
+  //
+  Status = mVarPol->DisableVariablePolicy ();
+  UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS);
+
+  return UNIT_TEST_PASSED;
+} // LockPolicyEngineTests
+
+//
+// Save context and reboot after the lock policy test suite
+//
+STATIC
+VOID
+SaveContextAndReboot (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+
+  //
+  // Now, save all the data associated with this framework.
+  // TODO: Need to add to the UnitTestFrameworkPkg
+  Status = SaveFrameworkState( GetActiveFrameworkHandle(), NULL, 0 );
+
+  //
+  // If we're all good, let's book...
+  if (!EFI_ERROR( Status ))
+  {
+    //
+    // Next, we want to update the BootNext variable to USB
+    // so that we have a fighting chance of coming back here.
+    //
+    // TODO: Need to add to the UnitTestFrameworkPkg
+    // SetBootNextDevice();
+
+    //
+    // Reset
+    DEBUG(( DEBUG_INFO, "%a - Rebooting! Launch this test again once booted.\n", __FUNCTION__ ));
+    gRT->ResetSystem( EfiResetCold, EFI_SUCCESS, 0, NULL );
+    DEBUG(( DEBUG_ERROR, "%a - Unit test failed to quit! Framework can no longer be used!\n", __FUNCTION__ ));
+
+    //
+    // We REALLY shouldn't be here.
+    Status = EFI_ABORTED;
+  }
+
+  return;
+} // SaveContextAndReboot
+
+//
+// Disable policy tests:
+//
+UNIT_TEST_STATUS
+DisablePolicyEngineTests (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS  Status;
+  BOOLEAN     State;
+  UINT8       Value;
+
+  //
+  // First, we disable the variable policy
+  //
+  Status = mVarPol->DisableVariablePolicy ();
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  //
+  // Confirm it's disabled
+  //
+  Status = mVarPol->IsVariablePolicyEnabled (&State);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (State, FALSE);
+
+  //
+  // Try locking it?
+  //
+  Status = mVarPol->LockVariablePolicy ();
+  UT_LOG_INFO ("Locking VP after disabling it status: %r\n", Status);
+
+  //
+  // Try modifying the var from TestExistingVarLockNow
+  //
+  Value = 0xB5;
+  Status = gRT->SetVariable (L"ExistingLockNowVar",
+                             &mTestNamespaceGuid1,
+                             (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+                             sizeof (Value),
+                             &Value);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  return UNIT_TEST_PASSED;
+} // DisablePolicyEngineTests
+
+//
+// Final Cleanup: delete some variables earlier test cases created
+//
+STATIC
+VOID
+FinalCleanup (
+  IN UNIT_TEST_CONTEXT           Context
+  )
+{
+  EFI_STATUS Status;
+
+  Status = gRT->SetVariable (L"ExistingLockNowVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_LOG_INFO ("Delete ExistingLockNowVar status: %r\n", Status);
+
+  Status = gRT->SetVariable (L"ExistingLockOnCreateVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_LOG_INFO ("Delete ExistingLockOnCreateVar status: %r\n", Status);
+
+  Status = gRT->SetVariable (L"NonexistentLockOnCreateVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_LOG_INFO ("Delete NonexistentLockOnCreateVar status: %r\n", Status);
+
+  Status = gRT->SetVariable (L"NonexistentLockNowVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_LOG_INFO ("Delete NonexistentLockNowVar status: %r\n", Status);
+
+  Status = gRT->SetVariable (L"CantHaveAttrNoLockVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_LOG_INFO ("Delete CantHaveAttrNoLockVar status: %r\n", Status);
+
+  Status = gRT->SetVariable (L"NonexistentLockOnVarStateVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_LOG_INFO ("Delete NonexistentLockOnVarStateVar status: %r\n", Status);
+
+  Status = gRT->SetVariable (L"ExistingLockOnVarStateVar",
+                             &mTestNamespaceGuid1,
+                             0,
+                             0,
+                             NULL);
+  UT_LOG_INFO ("Delete ExistingLockOnVarStateVar status: %r\n", Status);
+} // FinalCleanup
+
+/**
+
+  Main fuction sets up the unit test environment
+
+**/
+EFI_STATUS
+UefiMain (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE* SystemTable)
+{
+  EFI_STATUS                  Status;
+  UNIT_TEST_FRAMEWORK_HANDLE  mFw = NULL;
+  UNIT_TEST_SUITE_HANDLE      GettingStartedTestSuite;
+  UNIT_TEST_SUITE_HANDLE      NoLockPoliciesTestSuite;
+  UNIT_TEST_SUITE_HANDLE      LockNowPoliciesTestSuite;
+  UNIT_TEST_SUITE_HANDLE      LockOnCreatePoliciesTestSuite;
+  UNIT_TEST_SUITE_HANDLE      LockOnVarStatePoliciesTestSuite;
+  UNIT_TEST_SUITE_HANDLE      InvalidPoliciesTestSuite;
+  UNIT_TEST_SUITE_HANDLE      DumpPolicyTestSuite;
+  UNIT_TEST_SUITE_HANDLE      PolicyVersionTestSuite;
+  UNIT_TEST_SUITE_HANDLE      LockPolicyTestSuite;
+  UNIT_TEST_SUITE_HANDLE      DisablePolicyTestSuite;
+
+  GettingStartedTestSuite = NULL;
+
+  DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION));
+
+  //
+  // Start setting up the test framework for running the tests.
+  //
+  Status = InitUnitTestFramework (&mFw, UNIT_TEST_APP_NAME, gEfiCallerBaseName, UNIT_TEST_APP_VERSION);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));
+    goto EXIT;
+  }
+
+  //
+  // Test suite 1: Getting Started. Get VP protocol, check state, log revision
+  //
+  Status = CreateUnitTestSuite (&GettingStartedTestSuite, mFw, "Getting Started", "Common.VP.GettingStarted", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Getting Started Test Suite\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+  AddTestCase (GettingStartedTestSuite, "Confirm VP is enabled", "Common.VP.GettingStarted.CheckVpEnabled", CheckVpEnabled, LocateVarPolicyPreReq, NULL, NULL);
+  AddTestCase (GettingStartedTestSuite, "Check VP revision", "Common.VP.GettingStarted.CheckVpRevision", CheckVpRevision, LocateVarPolicyPreReq, NULL, NULL);
+
+  //
+  // Test suite 2: Test NoLock Policies
+  //
+  Status = CreateUnitTestSuite (&NoLockPoliciesTestSuite, mFw, "Exercise NoLock Policies", "Common.VP.NoLockPolicies", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the NoLock Policies Test Suite\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+  AddTestCase (NoLockPoliciesTestSuite, "Test Min Size enforcement in NoLock policy", "Common.VP.NoLockPolicies.TestMinSizeNoLock", TestMinSizeNoLock, LocateVarPolicyPreReq, NULL, NULL);
+  AddTestCase (NoLockPoliciesTestSuite, "Test Max Size enforcement in NoLock policy", "Common.VP.NoLockPolicies.TestMaxSizeNoLock", TestMaxSizeNoLock, LocateVarPolicyPreReq, NULL, NULL);
+  AddTestCase (NoLockPoliciesTestSuite, "Test Must Have Attribute enforcement in NoLock policy", "Common.VP.NoLockPolicies.TestMustHaveAttrNoLock", TestMustHaveAttrNoLock, LocateVarPolicyPreReq, NULL, NULL);
+  AddTestCase (NoLockPoliciesTestSuite, "Test Can't Have Attribute enforcement in NoLock policy", "Common.VP.NoLockPolicies.TestCantHaveAttrNoLock", TestCantHaveAttrNoLock, LocateVarPolicyPreReq, NULL, NULL);
+  AddTestCase (NoLockPoliciesTestSuite, "Test Max Size enforcement in NoLock policy for entire namespace", "Common.VP.NoLockPolicies.TestMaxSizeNamespaceNoLock", TestMaxSizeNamespaceNoLock, LocateVarPolicyPreReq, NULL, NULL);
+  AddTestCase (NoLockPoliciesTestSuite, "Test Must Have Attribute enforcement in NoLock policy with wildcards", "Common.VP.NoLockPolicies.TestMustHaveAttrWildcardNoLock", TestMustHaveAttrWildcardNoLock, LocateVarPolicyPreReq, NULL, NULL);
+  AddTestCase (NoLockPoliciesTestSuite, "Test policy prioritization between namespace-wide, wildcard, and var-specific policies", "Common.VP.NoLockPolicies.TestPolicyprioritizationNoLock", TestPolicyprioritizationNoLock, LocateVarPolicyPreReq, NULL, NULL);
+
+  //
+  // Test suite 3: Test LockNow policies
+  //
+  Status = CreateUnitTestSuite (&LockNowPoliciesTestSuite, mFw, "Exercise LockNow Policies", "Common.VP.LockNowPolicies", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the LockNow Policies Test Suite\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+  AddTestCase (LockNowPoliciesTestSuite, "Test LockNow policy for a pre-existing variable", "Common.VP.LockNowPolicies.TestExistingVarLockNow", TestExistingVarLockNow, LocateVarPolicyPreReq, NULL, NULL);
+  AddTestCase (LockNowPoliciesTestSuite, "Test LockNow policy for a nonexistent variable", "Common.VP.LockNowPolicies.TestNonexistentVarLockNow", TestNonexistentVarLockNow, LocateVarPolicyPreReq, NULL, NULL);
+
+  //
+  // Test suite 4: Test LockOnCreate policies
+  //
+  Status = CreateUnitTestSuite (&LockOnCreatePoliciesTestSuite, mFw, "Exercise LockOnCreate Policies", "Common.VP.LockOnCreate", NULL, NULL);
+  if (EFI_ERROR (Status))
+  {
+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the LockOnCreate Policies Test Suite\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+  AddTestCase (LockOnCreatePoliciesTestSuite, "Test LockOnCreate policy for a pre-existing variable", "Common.VP.LockOnCreate.TestExistingVarLockOnCreate", TestExistingVarLockOnCreate, LocateVarPolicyPreReq, NULL, NULL);
+  AddTestCase (LockOnCreatePoliciesTestSuite, "Test LockOnCreate policy for a nonexistent variable", "Common.VP.LockOnCreate.TestNonexistentVarLockOnCreate", TestNonexistentVarLockOnCreate, LocateVarPolicyPreReq, NULL, NULL);
+
+  //
+  // Test suite 5: Test LockOnVarState policies
+  //
+  Status = CreateUnitTestSuite (&LockOnVarStatePoliciesTestSuite, mFw, "Exercise LockOnVarState Policies", "Common.VP.LockOnVarState", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the LockOnVarState Policies Test Suite\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+  AddTestCase (LockOnVarStatePoliciesTestSuite, "Test LockOnVarState policy for a nonexistent variable", "Common.VP.LockOnVarState.TestLockOnVarStateBeforeCreate", TestLockOnVarStateBeforeCreate, LocateVarPolicyPreReq, NULL, NULL);
+  AddTestCase (LockOnVarStatePoliciesTestSuite, "Test LockOnVarState policy for a pre-existing variable", "Common.VP.LockOnVarState.TestLockOnVarStateAfterCreate", TestLockOnVarStateAfterCreate, LocateVarPolicyPreReq, NULL, NULL);
+  AddTestCase (LockOnVarStatePoliciesTestSuite, "Test LockOnVarState policy triggered by invalid-size variable", "Common.VP.LockOnVarState.TestLockOnVarStateInvalidLargeTrigger", TestLockOnVarStateInvalidLargeTrigger, LocateVarPolicyPreReq, NULL, NULL);
+  AddTestCase (LockOnVarStatePoliciesTestSuite, "Test LockOnVarState policy triggered by invalid-value variable", "Common.VP.LockOnVarState.TestLockOnVarStateWrongValueTrigger", TestLockOnVarStateWrongValueTrigger, LocateVarPolicyPreReq, NULL, NULL);
+
+  //
+  // Test suite 6: Test registering invalid policies
+  //
+  Status = CreateUnitTestSuite (&InvalidPoliciesTestSuite, mFw, "Attempt registering invalid policies", "Common.VP.InvalidPolicies", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Invalid Policies Test Suite\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+  AddTestCase (InvalidPoliciesTestSuite, "Test policy with invalid must-have attributes", "Common.VP.InvalidPolicies.TestInvalidAttributesPolicy", TestInvalidAttributesPolicy, LocateVarPolicyPreReq, NULL, NULL);
+  AddTestCase (InvalidPoliciesTestSuite, "Test policy with invalid attributes", "Common.VP.InvalidPolicies.TestLargeMinSizePolicy", TestLargeMinSizePolicy, LocateVarPolicyPreReq, NULL, NULL);
+  AddTestCase (InvalidPoliciesTestSuite, "Test policy with invalid attributes", "Common.VP.InvalidPolicies.TestZeroMaxSizePolicy", TestZeroMaxSizePolicy, LocateVarPolicyPreReq, NULL, NULL);
+  AddTestCase (InvalidPoliciesTestSuite, "Test policy with invalid type", "Common.VP.InvalidPolicies.TestInvalidPolicyTypePolicy", TestInvalidPolicyTypePolicy, LocateVarPolicyPreReq, NULL, NULL);
+
+  //
+  // Test suite 7: Test dumping the policy
+  //
+  Status = CreateUnitTestSuite (&DumpPolicyTestSuite, mFw, "Attempt dumping policy", "Common.VP.DumpPolicy", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Dump Policy Test Suite\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+  AddTestCase (DumpPolicyTestSuite, "Test dumping policy", "Common.VP.DumpPolicy.TestDumpPolicy", TestDumpPolicy, LocateVarPolicyPreReq, NULL, NULL);
+
+  //
+  // Test suite 8: Test policy version
+  //
+  Status = CreateUnitTestSuite (&PolicyVersionTestSuite, mFw, "Use non-zero policy version", "Common.VP.PolicyVersion", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Policy Version Test Suite\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+  AddTestCase (PolicyVersionTestSuite, "Test policy version", "Common.VP.DumpPolicy.TestPolicyVersion", TestPolicyVersion, LocateVarPolicyPreReq, NULL, NULL);
+
+  //
+  // Test suite 9: Lock VPE and test implications
+  //
+  Status = CreateUnitTestSuite (&LockPolicyTestSuite, mFw, "Lock policy, test it", "Common.VP.LockPolicyTests", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Lock Policy Test Suite\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+  AddTestCase (LockPolicyTestSuite, "Test locking policy", "Common.VP.LockPolicyTests.LockPolicyEngineTests", LockPolicyEngineTests, LocateVarPolicyPreReq, NULL, NULL);
+  AddTestCase (LockPolicyTestSuite, "Test locking policy", "Common.VP.LockPolicyTests.LockPolicyEngineTests", LockPolicyEngineTests, LocateVarPolicyPreReq, SaveContextAndReboot, NULL);
+
+  //
+  // Test suite 10: Disable var policy and confirm expected behavior
+  //
+  Status = CreateUnitTestSuite (&DisablePolicyTestSuite, mFw, "Disable policy, test it", "Common.VP.DisablePolicyTests", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Disable Policy Test Suite\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+  AddTestCase (DisablePolicyTestSuite, "Confirm VP is enabled", "Common.VP.DisablePolicyTests.CheckVpEnabled", CheckVpEnabled, LocateVarPolicyPreReq, NULL, NULL);
+  AddTestCase (DisablePolicyTestSuite, "Test LockNow policy for a pre-existing variable", "Common.VP.DisablePolicyTests.TestExistingVarLockNow", TestExistingVarLockNow, LocateVarPolicyPreReq, NULL, NULL);
+  AddTestCase (DisablePolicyTestSuite, "Test disabling policy", "Common.VP.DisablePolicyTests.DisablePolicyEngineTests", DisablePolicyEngineTests, LocateVarPolicyPreReq, FinalCleanup, NULL);
+
+  //
+  // Execute the tests.
+  //
+  Status = RunAllTestSuites (mFw);
+
+EXIT:
+  if (mFw) {
+    FreeUnitTestFramework (mFw);
+  }
+
+  return Status;
+} // UefiMain
diff --git a/MdeModulePkg/MdeModulePkg.ci.yaml b/MdeModulePkg/MdeModulePkg.ci.yaml
index 1cfc1328390e..88a192d0e2a8 100644
--- a/MdeModulePkg/MdeModulePkg.ci.yaml
+++ b/MdeModulePkg/MdeModulePkg.ci.yaml
@@ -35,7 +35,9 @@
             "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
         ],
         # For UEFI shell based apps
-        "AcceptableDependencies-UEFI_APPLICATION":[],
+        "AcceptableDependencies-UEFI_APPLICATION":[
+            "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
+        ],
         "IgnoreInf": []
     },
 
diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
index f0a75a3b337b..414a6c62dfdb 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -19,6 +19,8 @@
   BUILD_TARGETS                  = DEBUG|RELEASE|NOOPT
   SKUID_IDENTIFIER               = DEFAULT
 
+!include UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc
+
 [LibraryClasses]
   #
   # Entry point
@@ -314,6 +316,10 @@
   MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
   MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
   MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf
+  MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.inf {
+    <LibraryClasses>
+      UnitTestBootLib|UnitTestFrameworkPkg/Library/UnitTestBootLibNull/UnitTestBootLibNull.inf
+  }
   MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
   MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf
   MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf
diff --git a/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md
new file mode 100644
index 000000000000..804ad4173a5f
--- /dev/null
+++ b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md
@@ -0,0 +1,55 @@
+# variable Policy Unit Tests
+
+## &#x1F539; Copyright
+Copyright (C) Microsoft Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+## About This Test
+This test verifies functionality of the Variable Policy Protocol by registering various variable policies and exercising them, as well as tests locking the policy, disabling it, and dumping the policy entries.
+
+Only policies that are created as a part of this test will be tested.
+1. Try getting test context, if empty then get VP protocol, confirm that VP is not disabled by calling IsVariablePolicyEnabled. Log VP revision.
+2. "No lock" policies:
+    * check minsize enforcement
+    * check maxsize enforcement
+    * check musthave attr enforcement
+    * check canthave attr enforcement
+    * check one of the above with empty string policy i.e. name wildcard
+    * check another one of the above with a "#" containing policy string
+    * check policy prioritization by having a namespace-wide policy, a policy with a # wildcard, and a one-var specific policy and testing which one is enforced
+3. "Lock now" policies (means if the var doesn't exist, it won't be created; if one exists, it can't be updated):
+    * test a policy for an already existing variable, verify we can't write into that variable
+    * create a policy for a non-existing variable and attempt to register such var
+4. "Lock on create" policies (means the var can still be created, but no updates later, existing vars can't be updated):
+    * create a var, lock it with LockOnCreate, attempt to update its contents
+    * create LockOnCreate VP, attempt to create var with invalid size, then invalid attr, then create valid var, attempt to update its contents
+5. "Lock on var state" policies (means the var protected by this policy can't be created or updated once the trigger is set)
+    * create VP, trigger lock with a valid var, attempt to create a locked var, then modify the trigger var, create locked var
+    * create VP, create targeted var, modify it, trigger lock, attempt to modify var
+    * create VP, trigger lock with invalid (larger than one byte) var, see if VPE allows creation of the locked var (it should allow)
+    * create VP, set locking var with wrong value, see if VPE allows creation of the locked var (should allow)
+6. Attempt registering invalid policy entries
+    * invalid required and banned attributes
+    * large min size - let's say 2GB
+    * max size equal to 0
+    * invalid policy type
+7. Exercise dumping policy. No need to check the validity of the dump blob.
+8. Test registering a policy with a random version.
+9. Lock VPE, make sure old policies are enforced, new ones can't be registered.
+    * Register a LockOnCreate policy
+    * Lock VPE
+    * Test locking it again.
+    * Verify one of the prior policies is enforced
+    * Make sure we can create variables even if those are protected by LockOnCreate policy, after locking the VPE
+    * Attempt to register new policies
+    * Make sure can't disable VPE
+    * Cleanup: save context and reboot
+10. Disable variable policy and try some things
+    * Locate Variable Policy Protocol
+    * Make sure VP is enabled
+    * Register a policy
+    * Disable VPE
+    * Call IsVariablePolicyEnabled to confirm it's disabled.
+    * Make sure can't lock policy
+    * Make sure the policy from a is no longer enforced
+    * Final cleanup: delete vars that were created in some earlier test suites
diff --git a/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.inf b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.inf
new file mode 100644
index 000000000000..6cb5c2f18612
--- /dev/null
+++ b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTestApp.inf
@@ -0,0 +1,42 @@
+## @file
+# Uefi Shell based Application that unit tests the Variable Policy Protocol
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = VariablePolicyFuncTestApp
+  FILE_GUID                      = B653C4C3-3FCC-4B6C-8051-5F692AEAECBA
+  MODULE_TYPE                    = UEFI_APPLICATION
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = UefiMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = X64 AARCH64
+#
+
+[Sources]
+  VariablePolicyFuncTestApp.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+
+[LibraryClasses]
+  UefiApplicationEntryPoint
+  BaseLib
+  UnitTestLib
+  UnitTestBootLib
+  PrintLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  MemoryAllocationLib
+  VariablePolicyHelperLib
+
+[Protocols]
+  gVariablePolicyProtocolGuid
-- 
2.16.3.windows.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#59243): https://edk2.groups.io/g/devel/message/59243
Mute This Topic: https://groups.io/mt/74153784/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-




More information about the edk2-devel-archive mailing list