@joebigelow / wix-1 / commits / ed0ef472

Add test for apuputil and fix descending sorting.

Sean Hall committed Mar 30, 2021 at 17:15 UTC ed0ef472c76ac0d2a3d7a138e4f3b7ad950a56bc
8 files changed +155 -19
src/dutil/apuputil.cpp
+15 -12
@@ -208,7 +208,6 @@ static HRESULT ProcessEntry(
208 )
209 {
210 HRESULT hr = S_OK;
211 - BOOL fVersionFound = FALSE;
211 int nCompareResult = 0;
212
213 // First search the ATOM entry's custom elements to try and find the application update information.
@@ -255,25 +254,26 @@ static HRESULT ProcessEntry(
254 {
255 hr = VerParseVersion(pElement->wzValue, 0, FALSE, &pApupEntry->pVersion);
256 ApupExitOnFailure(hr, "Failed to parse version string '%ls' from ATOM entry.", pElement->wzValue);
258 -
259 - fVersionFound = TRUE;
257 }
258 }
259 }
260
261 // If there is no application identity or no version, skip the whole thing.
265 - if ((!pApupEntry->wzApplicationId && !wzDefaultAppId) || !fVersionFound)
262 + if ((!pApupEntry->wzApplicationId && !wzDefaultAppId) || !pApupEntry->pVersion)
263 {
264 ExitFunction1(hr = S_FALSE); // skip this update since it has no application id or version.
265 }
266
270 - hr = VerCompareParsedVersions(pApupEntry->pUpgradeVersion, pApupEntry->pVersion, &nCompareResult);
271 - ApupExitOnFailure(hr, "Failed to compare version to upgrade version.");
272 -
273 - if (nCompareResult >= 0)
267 + if (pApupEntry->pUpgradeVersion)
268 {
275 - hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
276 - ApupExitOnRootFailure(hr, "Upgrade version is greater than or equal to application version.");
269 + hr = VerCompareParsedVersions(pApupEntry->pUpgradeVersion, pApupEntry->pVersion, &nCompareResult);
270 + ApupExitOnFailure(hr, "Failed to compare version to upgrade version.");
271 +
272 + if (nCompareResult >= 0)
273 + {
274 + hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
275 + ApupExitOnRootFailure(hr, "Upgrade version is greater than or equal to application version.");
276 + }
277 }
278
279 if (pAtomEntry->wzTitle)
@@ -443,11 +443,14 @@ static __callback int __cdecl CompareEntries(
443 VerCompareParsedVersions(pEntryLeft->pUpgradeVersion, pEntryRight->pUpgradeVersion, &ret);
444 if (0 == ret)
445 {
446 - ret = (pEntryRight->dw64TotalSize < pEntryLeft->dw64TotalSize) ? -1 :
447 - (pEntryRight->dw64TotalSize > pEntryLeft->dw64TotalSize) ? 1 : 0;
446 + ret = (pEntryLeft->dw64TotalSize < pEntryRight->dw64TotalSize) ? -1 :
447 + (pEntryLeft->dw64TotalSize > pEntryRight->dw64TotalSize) ? 1 : 0;
448 }
449 }
450
451 + // Sort descending.
452 + ret = -ret;
453 +
454 return ret;
455 }
456
src/dutil/inc/verutil.h
+2 -2
@@ -34,8 +34,8 @@ typedef struct _VERUTIL_VERSION
34
35 *******************************************************************/
36 HRESULT DAPI VerCompareParsedVersions(
37 - __in VERUTIL_VERSION* pVersion1,
38 - __in VERUTIL_VERSION* pVersion2,
37 + __in_opt VERUTIL_VERSION* pVersion1,
38 + __in_opt VERUTIL_VERSION* pVersion2,
39 __out int* pnResult
40 );
41
src/dutil/verutil.cpp
+12 -4
@@ -40,8 +40,8 @@ static HRESULT CompareVersionSubstring(
40
41
42 DAPI_(HRESULT) VerCompareParsedVersions(
43 - __in VERUTIL_VERSION* pVersion1,
44 - __in VERUTIL_VERSION* pVersion2,
43 + __in_opt VERUTIL_VERSION* pVersion1,
44 + __in_opt VERUTIL_VERSION* pVersion2,
45 __out int* pnResult
46 )
47 {
@@ -50,8 +50,8 @@ DAPI_(HRESULT) VerCompareParsedVersions(
50 DWORD cMaxReleaseLabels = 0;
51 BOOL fCompareMetadata = FALSE;
52
53 - if (!pVersion1 || !pVersion1->sczVersion ||
54 - !pVersion2 || !pVersion2->sczVersion)
53 + if (pVersion1 && !pVersion1->sczVersion ||
54 + pVersion2 && !pVersion2->sczVersion)
55 {
56 ExitFunction1(hr = E_INVALIDARG);
57 }
@@ -60,6 +60,14 @@ DAPI_(HRESULT) VerCompareParsedVersions(
60 {
61 ExitFunction1(nResult = 0);
62 }
63 + else if (pVersion1 && !pVersion2)
64 + {
65 + ExitFunction1(nResult = 1);
66 + }
67 + else if (!pVersion1 && pVersion2)
68 + {
69 + ExitFunction1(nResult = -1);
70 + }
71
72 nResult = CompareDword(pVersion1->dwMajor, pVersion2->dwMajor);
73 if (0 != nResult)
src/test/DUtilUnitTest/ApupUtilTests.cpp new
+46
@@ -0,0 +1,46 @@
1 +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2 +
3 +#include "precomp.h"
4 +
5 +using namespace System;
6 +using namespace Xunit;
7 +using namespace WixBuildTools::TestSupport;
8 +
9 +namespace DutilTests
10 +{
11 + public ref class ApupUtil
12 + {
13 + public:
14 + [Fact]
15 + void AllocChainFromAtomSortsDescending()
16 + {
17 + HRESULT hr = S_OK;
18 + ATOM_FEED* pFeed = NULL;
19 + APPLICATION_UPDATE_CHAIN* pChain = NULL;
20 +
21 + DutilInitialize(&DutilTestTraceError);
22 +
23 + try
24 + {
25 + XmlInitialize();
26 + NativeAssert::Succeeded(hr, "Failed to initialize Xml.");
27 +
28 + pin_ptr<const wchar_t> feedFilePath = PtrToStringChars(TestData::Get("TestData", "ApupUtilTests", "FeedBv2.0.xml"));
29 + hr = AtomParseFromFile(feedFilePath, &pFeed);
30 + NativeAssert::Succeeded(hr, "Failed to parse feed: {0}", feedFilePath);
31 +
32 + hr = ApupAllocChainFromAtom(pFeed, &pChain);
33 + NativeAssert::Succeeded(hr, "Failed to get chain from feed.");
34 +
35 + Assert::Equal(3ul, pChain->cEntries);
36 + NativeAssert::StringEqual(L"Bundle v2.0", pChain->rgEntries[0].wzTitle);
37 + NativeAssert::StringEqual(L"Bundle v1.0", pChain->rgEntries[1].wzTitle);
38 + NativeAssert::StringEqual(L"Bundle v1.0-preview", pChain->rgEntries[2].wzTitle);
39 + }
40 + finally
41 + {
42 + DutilUninitialize();
43 + }
44 + }
45 + };
46 +}
src/test/DUtilUnitTest/DUtilUnitTest.vcxproj
+4
@@ -30,6 +30,7 @@
30 <ProjectAdditionalLinkLibraries>rpcrt4.lib;Mpr.lib;Ws2_32.lib;urlmon.lib;wininet.lib</ProjectAdditionalLinkLibraries>
31 </PropertyGroup>
32 <ItemGroup>
33 + <ClCompile Include="ApupUtilTests.cpp" />
34 <ClCompile Include="AssemblyInfo.cpp" />
35 <ClCompile Include="DictUtilTest.cpp" />
36 <ClCompile Include="DirUtilTests.cpp" />
@@ -59,6 +60,9 @@
60 <None Include="packages.config" />
61 <ResourceCompile Include="UnitTest.rc" />
62 </ItemGroup>
63 + <ItemGroup>
64 + <None Include="TestData\ApupUtilTests\FeedBv2.0.xml" CopyToOutputDirectory="PreserveNewest" />
65 + </ItemGroup>
66 <ItemGroup>
67 <Reference Include="System" />
68 <Reference Include="System.Core" />
src/test/DUtilUnitTest/DUtilUnitTest.vcxproj.filters
+3
@@ -15,6 +15,9 @@
15 </Filter>
16 </ItemGroup>
17 <ItemGroup>
18 + <ClCompile Include="ApupUtilTests.cpp">
19 + <Filter>Source Files</Filter>
20 + </ClCompile>
21 <ClCompile Include="AssemblyInfo.cpp">
22 <Filter>Source Files</Filter>
23 </ClCompile>
src/test/DUtilUnitTest/TestData/ApupUtilTests/FeedBv2.0.xml new
+68
@@ -0,0 +1,68 @@
1 +<?xml version='1.0' ?>
2 +<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3 +
4 +
5 +<feed xmlns="http://www.w3.org/2005/Atom" xmlns:as="http://appsyndication.org/2006/appsyn">
6 + <title type="text">BundleB v2.0</title>
7 + <subtitle type="text">Bundle Subtitle.</subtitle>
8 + <as:application type="application/exe">1116353B-7C6E-4C29-BFA1-D4A972CD421D</as:application>
9 + <updated>2014-07-14T12:39:00.000Z</updated>
10 + <id>http://localhost:9999/wix4/BundleB/feed</id>
11 + <link rel="self" type="application/atom+xml" href="http://localhost:9999/wix4/BundleB/feed"/>
12 + <generator version="0.1">manual build</generator>
13 + <entry>
14 + <title>Bundle v2.0</title>
15 + <id>v2.0</id>
16 + <author>
17 + <name>Bundle_Author</name>
18 + <uri>http://mycompany.com/software</uri>
19 + <email>Bundle_Author@mycompany.com</email>
20 + </author>
21 + <link rel="alternate" href="http://www.mycompany.com/content/view/software"/>
22 + <link rel="enclosure" href="http://localhost:9999/wix4/BundleB/2.0/BundleB.exe" length="0" type="application/octet-stream"/>
23 + <content type="html">
24 + &lt;p&gt;Change list:&lt;/p&gt;&lt;ul&gt;
25 + &lt;li&gt;Updated release.&lt;/li&gt;
26 + &lt;/ul&gt;
27 + </content>
28 + <as:version>2.0.0.0</as:version>
29 + <updated>2014-11-10T12:39:00.000Z</updated>
30 + </entry>
31 + <entry>
32 + <title>Bundle v1.0</title>
33 + <id>v1.0</id>
34 + <author>
35 + <name>Bundle_Author</name>
36 + <uri>http://mycompany.com/software</uri>
37 + <email>Bundle_Author@mycompany.com</email>
38 + </author>
39 + <link rel="alternate" href="http://www.mycompany.com/content/view/software"/>
40 + <link rel="enclosure" href="http://localhost:9999/wix4/BundleB/1.0/BundleB.exe" length="0" type="application/octet-stream"/>
41 + <content type="html">
42 + &lt;p&gt;Change list:&lt;/p&gt;&lt;ul&gt;
43 + &lt;li&gt;Initial release.&lt;/li&gt;
44 + &lt;/ul&gt;
45 + </content>
46 + <as:upgrade version="1.0.0.0-preview" />
47 + <as:version>1.0.0.0</as:version>
48 + <updated>2014-11-09T12:39:00.000Z</updated>
49 + </entry>
50 + <entry>
51 + <title>Bundle v1.0-preview</title>
52 + <id>v1.0-preview</id>
53 + <author>
54 + <name>Bundle_Author</name>
55 + <uri>http://mycompany.com/software</uri>
56 + <email>Bundle_Author@mycompany.com</email>
57 + </author>
58 + <link rel="alternate" href="http://www.mycompany.com/content/view/software"/>
59 + <link rel="enclosure" href="http://localhost:9999/wix4/BundleB/1.0-preview/BundleB.exe" length="10000" type="application/octet-stream"/>
60 + <content type="html">
61 + &lt;p&gt;Change list:&lt;/p&gt;&lt;ul&gt;
62 + &lt;li&gt;Initial release.&lt;/li&gt;
63 + &lt;/ul&gt;
64 + </content>
65 + <as:version>1.0.0.0</as:version>
66 + <updated>2014-11-09T12:39:00.000Z</updated>
67 + </entry>
68 +</feed>
src/test/DUtilUnitTest/precomp.h
+5 -1
@@ -11,6 +11,8 @@
11 #include "error.h"
12 #include <dutil.h>
13
14 +#include <verutil.h>
15 +#include <atomutil.h>
16 #include <dictutil.h>
17 #include <dirutil.h>
18 #include <fileutil.h>
@@ -21,8 +23,10 @@
23 #include <strutil.h>
24 #include <monutil.h>
25 #include <regutil.h>
26 +#include <rssutil.h>
27 +#include <apuputil.h> // NOTE: this must come after atomutil.h and rssutil.h since it uses them.
28 #include <uriutil.h>
25 -#include <verutil.h>
29 +#include <xmlutil.h>
30
31 #pragma managed
32 #include <vcclr.h>