From nobody Thu May 9 21:21:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+106577+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+106577+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1688148877; cv=none; d=zohomail.com; s=zohoarc; b=lIAv6f2Bty2LpDRvaDuX/eifsSMv0cD+FPRqwx0ni6TAjLNXWHkhCOJoUIKjz+RMqkor8mFWdDMXcdaLIcxf7qAGyRy/C/461xDalG5haUMHVw4Wy0d3iAk2whbQuSAIEgEohXFJhZ0WMBuwvHsgBkWKZhEr19gwojQoDGm2V/k= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1688148877; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=+EOYZ1RfXO40k2hTDtzCg1aBWawfBakepjEC3mo75ug=; b=I+DnUdehjR5/jmTEidLDo6sJPHeSLz8ckzGkvdTqOoZpo6AKas+9PwD/MdWEo493VHvpsOti81BiSN6H6tmZuhtsxk37eQB3mUrleRBhLKvXBCrObBmLcmkggptq8ab3b0FfhmEgdcEo9C2RxepICQ7Jkbym1Bv0bLMBriQ8yHc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+106577+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1688148877465385.58168961441334; Fri, 30 Jun 2023 11:14:37 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id 0TEGYY1788612x9yNa0FhuwL; Fri, 30 Jun 2023 11:14:37 -0700 X-Received: from mail-pl1-f172.google.com (mail-pl1-f172.google.com [209.85.214.172]) by mx.groups.io with SMTP id smtpd.web11.21165.1688148876569255098 for ; Fri, 30 Jun 2023 11:14:36 -0700 X-Received: by mail-pl1-f172.google.com with SMTP id d9443c01a7336-1b852785a65so14163985ad.0 for ; Fri, 30 Jun 2023 11:14:36 -0700 (PDT) X-Gm-Message-State: wUQM7FzzM31AEIeTtw7svQtBx1787277AA= X-Google-Smtp-Source: ACHHUZ42NT6PrNTnJ0fEcnA+gDbGhvKZH67E2YDaiFg9YCfYEkaNNCxlZh0fOM4m6WCWDxtRF0F1HA== X-Received: by 2002:a17:902:ab05:b0:1b5:522a:1578 with SMTP id ik5-20020a170902ab0500b001b5522a1578mr8833782plb.29.1688148875731; Fri, 30 Jun 2023 11:14:35 -0700 (PDT) X-Received: from MININT-0U7P5GU.redmond.corp.microsoft.com ([2001:4898:80e8:35:2ff5:3633:349e:ab2f]) by smtp.gmail.com with ESMTPSA id v10-20020a1709028d8a00b001b80c67d78asm8172974plo.95.2023.06.30.11.14.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jun 2023 11:14:35 -0700 (PDT) From: "Kun Qin" To: devel@edk2.groups.io Cc: Sean Brogan , Michael Kubacki , Michael D Kinney Subject: [edk2-devel] [PATCH v3 1/1] UnitTestFrameworkPkg: UnitTestPersistenceLib: Save Unit Test Cache Option Date: Fri, 30 Jun 2023 11:14:29 -0700 Message-ID: <20230630181430.2128-2-kuqin12@gmail.com> In-Reply-To: <20230630181430.2128-1-kuqin12@gmail.com> References: <20230630181430.2128-1-kuqin12@gmail.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,kuqin12@gmail.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1688148877; bh=CottszrVVNMsiaIlCdDy/LwoUaFr9M+bqkujoFvNlX4=; h=Cc:Date:From:Reply-To:Subject:To; b=jtj66/i8bb7gxY4NQsciYET//E/mHGQ5I3TJgKhTCFtjrd/AXQjrl2F137RsA/ksfdT mfYpOSmTu3BRCbvUMHihsdvOoxrZpogNmYbUGi1R3/E5wqUZmoW8GjDzPbkK+ZW4/udvm HMafF75VRptm1ASSIP+kXZ464uX+TJNX15I= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1688148879126100009 Content-Type: text/plain; charset="utf-8" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4467 Current implementation of UnitTestFrameworkPkg for shell-based unit test will save the unit test cache to the same volume as the test application itself. This works as long as the test application is on a writable volume, such as USB or EFI partition. Instead of saving the files to the same file system of unit test application, this change will save the cache file to the path where the user ran this test application. This change then added an input argument to allow user to specify where to save such cache file through `--CachePath` shell argument to allow even more flexibility. This change was tested on proprietary physical hardware platforms and QEMU based virtual platform. Cc: Sean Brogan Cc: Michael Kubacki Cc: Michael D Kinney Signed-off-by: Kun Qin Reviewed-by: Michael D Kinney Reviewed-by: Michael Kubacki --- Notes: v2: - Adding input argument [Mike Kinney] v3: - No review, no change UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileSystem/UnitTe= stPersistenceLibSimpleFileSystem.c | 232 +++++++++++++------- 1 file changed, 157 insertions(+), 75 deletions(-) diff --git a/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileS= ystem/UnitTestPersistenceLibSimpleFileSystem.c b/UnitTestFrameworkPkg/Libra= ry/UnitTestPersistenceLibSimpleFileSystem/UnitTestPersistenceLibSimpleFileS= ystem.c index b59991683f48..8f7f03646cd5 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileSystem/U= nitTestPersistenceLibSimpleFileSystem.c +++ b/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileSystem/U= nitTestPersistenceLibSimpleFileSystem.c @@ -16,13 +16,16 @@ #include #include #include +#include #include #include =20 #define CACHE_FILE_SUFFIX L"_Cache.dat" =20 +CHAR16 *mCachePath =3D NULL; + /** - Generate the device path to the cache file. + Generate the file name and path to the cache file. =20 @param[in] FrameworkHandle A pointer to the framework that is being pe= rsisted. =20 @@ -31,8 +34,8 @@ =20 **/ STATIC -EFI_DEVICE_PATH_PROTOCOL * -GetCacheFileDevicePath ( +CHAR16 * +GetCacheFileName ( IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle ) { @@ -44,13 +47,11 @@ GetCacheFileDevicePath ( CHAR16 *TestName; UINTN DirectorySlashOffset; UINTN CacheFilePathLength; - EFI_DEVICE_PATH_PROTOCOL *CacheFileDevicePath; =20 - Framework =3D (UNIT_TEST_FRAMEWORK *)FrameworkHandle; - AppPath =3D NULL; - CacheFilePath =3D NULL; - TestName =3D NULL; - CacheFileDevicePath =3D NULL; + Framework =3D (UNIT_TEST_FRAMEWORK *)FrameworkHandle; + AppPath =3D NULL; + CacheFilePath =3D NULL; + TestName =3D NULL; =20 // // First, we need to get some information from the loaded image. @@ -85,35 +86,62 @@ GetCacheFileDevicePath ( // PathCleanUpDirectories (FileNameCopy); // if (PathRemoveLastItem (FileNameCopy)) { // - AppPath =3D ConvertDevicePathToText (LoadedImage->FilePath,= TRUE, TRUE); // NOTE: This must be freed. - DirectorySlashOffset =3D StrLen (AppPath); - // - // Make sure we didn't get any weird data. - // - if (DirectorySlashOffset =3D=3D 0) { - DEBUG ((DEBUG_ERROR, "%a - Weird 0-length string when processing app p= ath.\n", __func__)); - goto Exit; - } + if (mCachePath =3D=3D NULL) { + AppPath =3D ConvertDevicePathToText (LoadedImage->FilePath, TRUE, TRUE= ); // NOTE: This must be freed. + if (AppPath =3D=3D NULL) { + goto Exit; + } =20 - // - // Now that we know we have a decent string, let's take a deeper look. - // - do { - if (AppPath[DirectorySlashOffset] =3D=3D L'\\') { - break; + DirectorySlashOffset =3D StrLen (AppPath); + // + // Make sure we didn't get any weird data. + // + if (DirectorySlashOffset =3D=3D 0) { + DEBUG ((DEBUG_ERROR, "%a - Weird 0-length string when processing app= path.\n", __func__)); + goto Exit; } =20 - DirectorySlashOffset--; - } while (DirectorySlashOffset > 0); + // + // Now that we know we have a decent string, let's take a deeper look. + // + do { + if (AppPath[DirectorySlashOffset] =3D=3D L'\\') { + break; + } + + DirectorySlashOffset--; + } while (DirectorySlashOffset > 0); =20 - // - // After that little maneuver, DirectorySlashOffset should be pointing a= t the last '\' in AppString. - // That would be the path to the parent directory that the test app is e= xecuting from. - // Let's check and make sure that's right. - // - if (AppPath[DirectorySlashOffset] !=3D L'\\') { - DEBUG ((DEBUG_ERROR, "%a - Could not find a single directory separator= in app path.\n", __func__)); - goto Exit; + // + // After that little maneuver, DirectorySlashOffset should be pointing= at the last '\' in AppString. + // That would be the path to the parent directory that the test app is= executing from. + // Let's check and make sure that's right. + // + if (AppPath[DirectorySlashOffset] !=3D L'\\') { + DEBUG ((DEBUG_ERROR, "%a - Could not find a single directory separat= or in app path.\n", __func__)); + goto Exit; + } + } else { + AppPath =3D FullyQualifyPath (mCachePath); // NOTE: This must be freed. + if (AppPath =3D=3D NULL) { + goto Exit; + } + + DirectorySlashOffset =3D StrLen (AppPath); + + if (AppPath[DirectorySlashOffset - 1] !=3D L'\\') { + // Set the slash if user did not specify it on the newly allocated p= ool + AppPath =3D ReallocatePool ( + (DirectorySlashOffset + 1) * sizeof (CHAR16), + (DirectorySlashOffset + 2) * sizeof (CHAR16), + AppPath + ); + AppPath[DirectorySlashOffset] =3D L'\\'; + AppPath[DirectorySlashOffset + 1] =3D L'\0'; + } else { + // Otherwise the user input is good enough to go, mostly + DirectorySlashOffset--; + } } =20 // @@ -135,11 +163,6 @@ GetCacheFileDevicePath ( StrCatS (CacheFilePath, CacheFilePathLength, TestName); = // Copy the base name for the test cache. StrCatS (CacheFilePath, CacheFilePathLength, CACHE_FILE_SUFFIX); = // Copy the file suffix. =20 - // - // Finally, try to create the device path for the thing thing. - // - CacheFileDevicePath =3D FileDevicePath (LoadedImage->DeviceHandle, Cache= FilePath); - Exit: // // Free allocated buffers. @@ -148,15 +171,11 @@ Exit: FreePool (AppPath); } =20 - if (CacheFilePath !=3D NULL) { - FreePool (CacheFilePath); - } - if (TestName !=3D NULL) { FreePool (TestName); } =20 - return CacheFileDevicePath; + return CacheFilePath; } =20 /** @@ -175,21 +194,24 @@ DoesCacheExist ( IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle ) { - EFI_DEVICE_PATH_PROTOCOL *FileDevicePath; - EFI_STATUS Status; - SHELL_FILE_HANDLE FileHandle; + CHAR16 *FileName; + EFI_STATUS Status; + SHELL_FILE_HANDLE FileHandle; =20 // // NOTE: This devpath is allocated and must be freed. // - FileDevicePath =3D GetCacheFileDevicePath (FrameworkHandle); + FileName =3D GetCacheFileName (FrameworkHandle); + if (FileName =3D=3D NULL) { + return FALSE; + } =20 // // Check to see whether the file exists. If the file can be opened for // reading, it exists. Otherwise, probably not. // - Status =3D ShellOpenFileByDevicePath ( - &FileDevicePath, + Status =3D ShellOpenFileByName ( + FileName, &FileHandle, EFI_FILE_MODE_READ, 0 @@ -198,8 +220,8 @@ DoesCacheExist ( ShellCloseFile (&FileHandle); } =20 - if (FileDevicePath !=3D NULL) { - FreePool (FileDevicePath); + if (FileName !=3D NULL) { + FreePool (FileName); } =20 DEBUG ((DEBUG_VERBOSE, "%a - Returning %d\n", __func__, !EFI_ERROR (Stat= us))); @@ -229,10 +251,10 @@ SaveUnitTestCache ( IN UINTN SaveStateSize ) { - EFI_DEVICE_PATH_PROTOCOL *FileDevicePath; - EFI_STATUS Status; - SHELL_FILE_HANDLE FileHandle; - UINTN WriteCount; + CHAR16 *FileName; + EFI_STATUS Status; + SHELL_FILE_HANDLE FileHandle; + UINTN WriteCount; =20 // // Check the inputs for sanity. @@ -245,13 +267,16 @@ SaveUnitTestCache ( // Determine the path for the cache file. // NOTE: This devpath is allocated and must be freed. // - FileDevicePath =3D GetCacheFileDevicePath (FrameworkHandle); + FileName =3D GetCacheFileName (FrameworkHandle); + if (FileName =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } =20 // // First lets open the file if it exists so we can delete it...This is t= he work around for truncation // - Status =3D ShellOpenFileByDevicePath ( - &FileDevicePath, + Status =3D ShellOpenFileByName ( + FileName, &FileHandle, (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE), 0 @@ -270,8 +295,8 @@ SaveUnitTestCache ( // // Now that we know the path to the file... let's open it for writing. // - Status =3D ShellOpenFileByDevicePath ( - &FileDevicePath, + Status =3D ShellOpenFileByName ( + FileName, &FileHandle, (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CRE= ATE), 0 @@ -304,8 +329,8 @@ SaveUnitTestCache ( ShellCloseFile (&FileHandle); =20 Exit: - if (FileDevicePath !=3D NULL) { - FreePool (FileDevicePath); + if (FileName !=3D NULL) { + FreePool (FileName); } =20 return Status; @@ -334,13 +359,13 @@ LoadUnitTestCache ( OUT UINTN *SaveStateSize ) { - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *FileDevicePath; - SHELL_FILE_HANDLE FileHandle; - BOOLEAN IsFileOpened; - UINT64 LargeFileSize; - UINTN FileSize; - VOID *Buffer; + EFI_STATUS Status; + CHAR16 *FileName; + SHELL_FILE_HANDLE FileHandle; + BOOLEAN IsFileOpened; + UINT64 LargeFileSize; + UINTN FileSize; + VOID *Buffer; =20 IsFileOpened =3D FALSE; Buffer =3D NULL; @@ -356,13 +381,16 @@ LoadUnitTestCache ( // Determine the path for the cache file. // NOTE: This devpath is allocated and must be freed. // - FileDevicePath =3D GetCacheFileDevicePath (FrameworkHandle); + FileName =3D GetCacheFileName (FrameworkHandle); + if (FileName =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } =20 // // Now that we know the path to the file... let's open it for writing. // - Status =3D ShellOpenFileByDevicePath ( - &FileDevicePath, + Status =3D ShellOpenFileByName ( + FileName, &FileHandle, EFI_FILE_MODE_READ, 0 @@ -407,8 +435,8 @@ Exit: // // Free allocated buffers // - if (FileDevicePath !=3D NULL) { - FreePool (FileDevicePath); + if (FileName !=3D NULL) { + FreePool (FileName); } =20 if (IsFileOpened) { @@ -426,3 +454,57 @@ Exit: *SaveData =3D Buffer; return Status; } + +/** + Shell based UnitTestPersistenceLib library constructor. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor finished successfully. + @retval Others Error codes returned from gBS->HandleProtocol. + **/ +EFI_STATUS +EFIAPI +UnitTestPersistenceLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + UINTN Index; + UINTN Argc; + CHAR16 **Argv; + EFI_STATUS Status; + EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters; + + Status =3D gBS->HandleProtocol ( + gImageHandle, + &gEfiShellParametersProtocolGuid, + (VOID **)&ShellParameters + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto Done; + } + + Argc =3D ShellParameters->Argc; + Argv =3D ShellParameters->Argv; + + Status =3D EFI_SUCCESS; + if ((Argc > 1) && (Argv !=3D NULL)) { + // This might be our cue, check for whether we need to do anything + for (Index =3D 1; Index < Argc; Index++) { + if (StrCmp (Argv[Index], L"--CachePath") =3D=3D 0) { + // Need to update the potential cache path to designated path + if (Index < Argc - 1) { + mCachePath =3D Argv[Index + 1]; + } else { + Print (L" --CachePath \n"); + } + } + } + } + +Done: + return Status; +} --=20 2.41.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#106577): https://edk2.groups.io/g/devel/message/106577 Mute This Topic: https://groups.io/mt/99878682/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-