From bc98a96f256d30aa459df48a6905c0c8df06b63a Mon Sep 17 00:00:00 2001 From: Jason Naylor Date: Fri, 12 Jul 2019 11:13:50 -0500 Subject: [PATCH 1/2] Support more reliable patching * Use an environment var instead of 'number of days' if set * Add CommonAssemblyInfo to Paratext8Plugin * Update comments in CommonAssemblyInfoTemplate Change-Id: Ic8d71929c4cf0600b0621a0def6645bacee9710e --- Build/FwBuildTasks.dll | Bin 186368 -> 186368 bytes Build/Src/FwBuildTasks/FwBuildTasks.csproj | 5 ++--- Build/Src/FwBuildTasks/Substitute.cs | 16 +++++++++++--- Src/CommonAssemblyInfoTemplate.cs | 10 ++++----- Src/Paratext8Plugin/Paratext8Plugin.csproj | 5 ++++- .../Properties/AssemblyInfo.cs | 20 ++---------------- Src/bldinc.h | 18 ++++------------ Src/views/Views.rc | 5 ++--- 8 files changed, 32 insertions(+), 47 deletions(-) diff --git a/Build/FwBuildTasks.dll b/Build/FwBuildTasks.dll index 52dde3a157135f10391d307b5a0396dc6df9edb3..fe41f3abf6fadb6cdd15485b0c2147871edfb87a 100644 GIT binary patch delta 53674 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 delta 53678 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­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 Z{iqu3h$)do4VXW?IsNbI8`)HD`+qj%Rk{EG diff --git a/Build/Src/FwBuildTasks/FwBuildTasks.csproj b/Build/Src/FwBuildTasks/FwBuildTasks.csproj index 3b1fe0dd5a..36e9e44600 100644 --- a/Build/Src/FwBuildTasks/FwBuildTasks.csproj +++ b/Build/Src/FwBuildTasks/FwBuildTasks.csproj @@ -94,9 +94,8 @@ ..\..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll - - False - ..\..\..\Output\Release\SIL.TestUtilities.dll + + ..\..\..\Output\Debug\SIL.TestUtilities.dll diff --git a/Build/Src/FwBuildTasks/Substitute.cs b/Build/Src/FwBuildTasks/Substitute.cs index 7e0de0605d..e9965ed91f 100644 --- a/Build/Src/FwBuildTasks/Substitute.cs +++ b/Build/Src/FwBuildTasks/Substitute.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2018 SIL International +// Copyright (c) 2018 SIL International // This software is licensed under the LGPL, version 2.1 or later // (http://www.gnu.org/licenses/lgpl-2.1.html) @@ -74,8 +74,18 @@ public override bool Execute() fileContents = regex.Replace(fileContents, string.Format("{0:dd}", DateTime.Now)); regex = new Regex("\\$NUMBEROFDAYS"); - fileContents = regex.Replace(fileContents, - Convert.ToInt32(Math.Truncate(DateTime.Now.ToOADate())).ToString()); + var numberOfDays = Convert.ToInt32(Math.Truncate(DateTime.Now.ToOADate())).ToString(); + fileContents = regex.Replace(fileContents, numberOfDays); + + // Jenkins builds should set the BUILD_NUMBER in the environment + var buildNumber = Environment.GetEnvironmentVariable("BUILD_NUMBER"); + if (string.IsNullOrEmpty(buildNumber)) + { + // fall back to number of days if no BUILD_NUMBER is in the environment + buildNumber = numberOfDays; + } + regex = new Regex("\\$BUILDNUMBER"); + fileContents = regex.Replace(fileContents, buildNumber); regex = new Regex("\\$GENERATEDFILECOMMENT"); if (regex.IsMatch(fileContents)) diff --git a/Src/CommonAssemblyInfoTemplate.cs b/Src/CommonAssemblyInfoTemplate.cs index ea81e04e3d..a8fd6ebe47 100644 --- a/Src/CommonAssemblyInfoTemplate.cs +++ b/Src/CommonAssemblyInfoTemplate.cs @@ -1,4 +1,4 @@ -/*---------------------------------------------------------------------------------------------- +/*---------------------------------------------------------------------------------------------- Copyright (c) 2002-2013 SIL International This software is licensed under the LGPL, version 2.1 or later (http://www.gnu.org/licenses/lgpl-2.1.html) @@ -25,9 +25,9 @@ Some are kept here so that certain symbols (starting with $ in the template) can [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Format: Version.Milestone.Year.MMDDL -[assembly: AssemblyFileVersion("$!{FWMAJOR:0}.$!{FWMINOR:0}.$!{FWREVISION:0}.$NUMBEROFDAYS")] -// Format: FwMajorVersion.FwMinorVersion +// Format: Major.Minor.Revision.BuildNumber +[assembly: AssemblyFileVersion("$!{FWMAJOR:0}.$!{FWMINOR:0}.$!{FWREVISION:0}.$BUILDNUMBER")] +// Format: FwMajorVersion.FwMinorVersion Alpha/Beta/RC [assembly: AssemblyInformationalVersionAttribute("$!{FWMAJOR:0}.$!{FWMINOR:0} $!FWBETAVERSION")] -// Format: Version.Milestone.0.Level +// Format: Major.Minor.Revision.BuildNumber? [assembly: AssemblyVersion("$!{FWMAJOR:0}.$!{FWMINOR:0}.$!{FWREVISION:0}.*")] diff --git a/Src/Paratext8Plugin/Paratext8Plugin.csproj b/Src/Paratext8Plugin/Paratext8Plugin.csproj index a20676a334..42b1b279d0 100644 --- a/Src/Paratext8Plugin/Paratext8Plugin.csproj +++ b/Src/Paratext8Plugin/Paratext8Plugin.csproj @@ -1,4 +1,4 @@ - + @@ -93,6 +93,9 @@ + + CommonAssemblyInfo.cs + \ No newline at end of file diff --git a/Src/Paratext8Plugin/Properties/AssemblyInfo.cs b/Src/Paratext8Plugin/Properties/AssemblyInfo.cs index c6f6f4778e..27b1df565c 100644 --- a/Src/Paratext8Plugin/Properties/AssemblyInfo.cs +++ b/Src/Paratext8Plugin/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following @@ -7,10 +6,6 @@ // associated with an assembly. [assembly: AssemblyTitle("Paratext8Plugin")] [assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Paratext8Plugin")] -[assembly: AssemblyCopyright("Copyright © SIL International 2017")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from @@ -20,15 +15,4 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("b661c6ae-999d-4ba8-80c1-ea853f6d6a30")] -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +// Version information comes from CommonAssemblyInfo diff --git a/Src/bldinc.h b/Src/bldinc.h index 988aadd3f2..cc8b4a758b 100644 --- a/Src/bldinc.h +++ b/Src/bldinc.h @@ -1,20 +1,10 @@ #define MAJOR_VERSION $!{FWMAJOR:0} #define MINOR_VERSION $!{FWMINOR:0} #define SUITE_REVISION $!{FWREVISION:0} -//#define DN_MAJOR_VERSION $!{DNMAJOR:0} -//#define DN_MINOR_VERSION $!{DNMINOR:0} -//#define DN_REVISION $!{DNREVISION:0} -//#define WP_MAJOR_VERSION $!{WPMAJOR:0} -//#define WP_MINOR_VERSION $!{WPMINOR:0} -//#define WP_REVISION $!{WPREVISION:0} -//#define TLE_MAJOR_VERSION $!{TLEMAJOR:0} -//#define TLE_MINOR_VERSION $!{TLEMINOR:0} -//#define TLE_REVISION $!{TLEREVISION:0} #define YEAR $YEAR -//#define DAY_MONTH_BUILDLVL $MONTH$DAY$!{BUILD_LEVEL:9} -#define NUMBER_OF_DAYS $NUMBEROFDAYS -#define STR_PRODUCT "$!{FWMAJOR:0}.$!{FWMINOR:0}.$!{FWREVISION:0}.$NUMBEROFDAYS\0" +#define BUILD_NUMBER $BUILDNUMBER +#define STR_PRODUCT "$!{FWMAJOR:0}.$!{FWMINOR:0}.$!{FWREVISION:0}.$BUILDNUMBER\0" #define FWSUITE_VERSION "$!{FWMAJOR:0}.$!{FWMINOR:0}.$!{FWREVISION:0}.0\0" -#define COPYRIGHT "Copyright © 2002-$YEAR SIL International\0" -#define COPYRIGHTRESERVED "Copyright © 2002-$YEAR SIL International. All rights reserved." +#define COPYRIGHT "Copyright © 2002-$YEAR SIL International\0" +#define COPYRIGHTRESERVED "Copyright © 2002-$YEAR SIL International. All rights reserved." #define REGISTRYPATHWITHVERSION _T("Software\\SIL\\FieldWorks\\$!{FWMAJOR:0}") diff --git a/Src/views/Views.rc b/Src/views/Views.rc index 243492398e..0e8b38679a 100644 --- a/Src/views/Views.rc +++ b/Src/views/Views.rc @@ -33,8 +33,7 @@ Description: #include "VwResources.h" VS_VERSION_INFO VERSIONINFO // NOTE: These defines are in bldinc.h. - FILEVERSION MAJOR_VERSION,MINOR_VERSION,SUITE_REVISION,NUMBER_OF_DAYS - PRODUCTVERSION MAJOR_VERSION,MINOR_VERSION,SUITE_REVISION,NUMBER_OF_DAYS + PRODUCTVERSION MAJOR_VERSION,MINOR_VERSION,SUITE_REVISION,BUILD_NUMBER FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -52,7 +51,7 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "SIL International\0" VALUE "FileDescription", "Fieldworks View support\0" - VALUE "FileVersion", STR_PRODUCT // Uses FILEVERSION. + VALUE "FileVersion", STR_PRODUCT VALUE "InternalName", "Views\0" VALUE "LegalCopyright", COPYRIGHT VALUE "LegalTrademarks", "\0" From 71697746d7cc318d16e30404db5426c44782e2eb Mon Sep 17 00:00:00 2001 From: Hasso Date: Fri, 28 Jun 2019 14:33:30 -0500 Subject: [PATCH 2/2] LT-14596: Automate Testing of Patch Installation - Add a target to build an installer and a test patch so that we can quickly test that each FLEx file is patched - Add a build step to record files expected to be installed (binaries installed by our installer; *not* merge modules, etc.) - Install a utility to read this list and verify installation Change-Id: I3dcfdcaa414075d6bd645ff084f04382cf9dca0f --- Build/FieldWorks.proj | 6 +- Build/FwBuildTasks.dll | Bin 186368 -> 187392 bytes Build/Installer.targets | 2 +- Build/InstallerTests.targets | 58 ++++++++ Build/Src/FwBuildTasks/FwBuildTasks.csproj | 1 + Build/Src/FwBuildTasks/LogMetadata.cs | 47 +++++++ Build/Src/FwBuildTasks/Md5Checksum.cs | 33 +++-- Src/InstallValidator/InstallValidator.cs | 107 +++++++++++++++ Src/InstallValidator/InstallValidator.csproj | 99 ++++++++++++++ .../InstallValidatorTests.cs | 126 ++++++++++++++++++ .../InstallValidatorTests.csproj | 109 +++++++++++++++ .../Properties/AssemblyInfo.cs | 21 +++ 12 files changed, 593 insertions(+), 16 deletions(-) create mode 100644 Build/InstallerTests.targets create mode 100644 Build/Src/FwBuildTasks/LogMetadata.cs create mode 100644 Src/InstallValidator/InstallValidator.cs create mode 100644 Src/InstallValidator/InstallValidator.csproj create mode 100644 Src/InstallValidator/InstallValidatorTests/InstallValidatorTests.cs create mode 100644 Src/InstallValidator/InstallValidatorTests/InstallValidatorTests.csproj create mode 100644 Src/InstallValidator/Properties/AssemblyInfo.cs diff --git a/Build/FieldWorks.proj b/Build/FieldWorks.proj index ef35795a0a..c8fe09b4a3 100644 --- a/Build/FieldWorks.proj +++ b/Build/FieldWorks.proj @@ -15,6 +15,7 @@ + @@ -60,8 +61,9 @@ - + + + - diff --git a/Build/FwBuildTasks.dll b/Build/FwBuildTasks.dll index fe41f3abf6fadb6cdd15485b0c2147871edfb87a..03a5574d4bdd85ec2633e1973ab4381ca0337128 100644 GIT binary patch delta 58202 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�Bg!@9yc3z6=irk zFc+_RqNkXTw*}>REx_A?g?LM_2(QI>OK>CJ4%~#-61?c|o~kD{$%WoOX|Fpp{Y$-E zeyI-^U+VFCm0i=N6_qUyRE?{VuenE-EgutDwtU*n z<;%+^moF}xvb+wDgL}r%5UQ&7Ihk7b{Bv@#vX8s9?B?5UF0Yd>$XYF7d|>(f@i&*v zEnhMDrh=PqT2htxyiBV5?MrfJoO@o`^4W+yqI^-ASjN0=?k;(AY#KSNWR{yQw(8#B zC+}1G@S7Gdshe6aJ;~V=@TWO&QZ2>0Wgp2wnm#J9Y<}Gf4KgjW?kz(V-H_qzi66Tv zKsyP1L)jZWwE}Oc?h?XYmpNY@iwX7}fmU6FmhNta>yBTUDib%0WzcUz>ymyGdZQdY zQ4UY35Ji;IUGR8t7ewxljM6o=zQ|{#^{)rw7oiVJ@ee;qh<}67Z;OG;@K3{!;M85X zS-sjfVZo)CRe!zo>F}!i-pPm?er$PN?1;#yc*SNS3? z0dc4C26lp^mpgQz&iN9i_Jl+3&>=&}w(fz+_E>j#Mcu={QC(#F1MLvRftTTtjwFm@ z>BbE+b}Mexv2CiO4AuQ@o2t~xA4<2kN>}OaT#j^yN=XbmWn%at{712D=?1Ehp6<9T zC);iAaB+(JdMk`Ooaj=H6nChC1fiW`2$Rrm3B)mo(`*qsRPK>1uQS7NAMac$OCegB$T zE+45{T&ME%-R{tisx5U`his^Nw@zJM=iWgplg)JlcB&XDcUSpdSGUX4Rl8qTy*wvT z-j9^a9Xja_T~Nw-#k4z7tdmu-yHxAAlPQV!7*?p0Reg4;E}oOI9>Ho7o}%ph(I1oI z4nLw%#M^hNo!*8+d{j?DP4)-tu7a}l*>h3f8`I3s!w*|31Qo- ze7n_92U5ZKL9%OhtAp}n)r2>cr}YkKDRw)W5V?A(LqT_7ui%b%4K#tXqER(m6NQ? zB%#@ou$&a=M0fa3jJ>K^Z>ptE$HCtoc)L@Ni(l6rep59#7L>qhL!dc);J~KI(o@6`%o^9#pN-oDUsTr4lF5 zL7dzV)wO;H>)3=N+;O2JRuV_579Ucb`knL&182`mKaM}7h^BO5@R@_uC`=zTl#vS$!t{4l?*S(rLLxz*q`INle5USjLFHIDgB3F0 z;o_o&cfh34S#|fjs&(uE)EYAvW~?JsPrZw^>&dF5_tb>=Bla$WV;fy4$*N`VsSDVV z{N$6pfwa89J6J4PlE21VjAKenoK!IB)?VWERh!cbH&*2QCTqa&*VBq-_@I)xx7}Q} zepSZ~t3&JaWt?mJHlr}UeugGbc%D%bDT-LXv*&tRK1el30CnYyaqqtJ1AxU%=bHKY&z^{-1hhLwFw ittxn24gQIA{;(S4{0i@>kk#tGb%`g`Uu0!(`~L$MOGL~7 delta 56764 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 diff --git a/Build/Installer.targets b/Build/Installer.targets index a9dc5f5164..aaaa2ba623 100644 --- a/Build/Installer.targets +++ b/Build/Installer.targets @@ -266,7 +266,7 @@ - + diff --git a/Build/InstallerTests.targets b/Build/InstallerTests.targets new file mode 100644 index 0000000000..b39ccb174b --- /dev/null +++ b/Build/InstallerTests.targets @@ -0,0 +1,58 @@ + + + + $(fwrt)\.. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(AppBuildDir)\$(BinDirSuffix)\installerTestMetadata.$(BuildVersion).csv + + + + + + + + + \ No newline at end of file diff --git a/Build/Src/FwBuildTasks/FwBuildTasks.csproj b/Build/Src/FwBuildTasks/FwBuildTasks.csproj index 36e9e44600..89b65889e3 100644 --- a/Build/Src/FwBuildTasks/FwBuildTasks.csproj +++ b/Build/Src/FwBuildTasks/FwBuildTasks.csproj @@ -109,6 +109,7 @@ + diff --git a/Build/Src/FwBuildTasks/LogMetadata.cs b/Build/Src/FwBuildTasks/LogMetadata.cs new file mode 100644 index 0000000000..c094e92870 --- /dev/null +++ b/Build/Src/FwBuildTasks/LogMetadata.cs @@ -0,0 +1,47 @@ +// Copyright (c) 2019 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) + +using System.Diagnostics; +using System.IO; +using FwBuildTasks; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +namespace SIL.FieldWorks.Build.Tasks +{ + /// + /// Generate a CSV file containing metadata about the specified files (MD5, date modified, etc.) + /// for use in testing installers and patchers + /// + public class LogMetadata : Task + { + [Required] + public string[] Files { get; set; } + + public string PathPrefixToDrop { get; set; } + + [Required] + public string LogFile { get; set; } + + public bool Overwrite { get; set; } + + public override bool Execute() + { + using (var writer = new StreamWriter(LogFile, !Overwrite)) + { + writer.WriteLine("File,MD5,Version,Modified"); + var lengthToDrop = string.IsNullOrEmpty(PathPrefixToDrop) ? 0 : PathPrefixToDrop.Length; + foreach (var file in Files) + { + var md5 = Md5Checksum.Compute(file); + // Some files have commas in their versions. Replace with another character because our CSV reader is cheap. + var version = FileVersionInfo.GetVersionInfo(file).FileVersion?.Replace(',', ';'); + var modified = File.GetLastWriteTimeUtc(file); + writer.WriteLine($"{file.Substring(lengthToDrop)}, {md5}, {version}, {modified:yyyy-MM-dd HH:mm:ss}"); + } + return true; + } + } + } +} diff --git a/Build/Src/FwBuildTasks/Md5Checksum.cs b/Build/Src/FwBuildTasks/Md5Checksum.cs index a5e6d2c9bc..d2fe529296 100644 --- a/Build/Src/FwBuildTasks/Md5Checksum.cs +++ b/Build/Src/FwBuildTasks/Md5Checksum.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2015 SIL International +// Copyright (c) 2015-2019 SIL International // This software is licensed under the LGPL, version 2.1 or later // (http://www.gnu.org/licenses/lgpl-2.1.html) @@ -13,6 +13,8 @@ namespace FwBuildTasks { public class Md5Checksum : Task { + private static readonly HashAlgorithm Hasher = HashAlgorithm.Create("MD5"); + [Required] public string SourceFile { get; set; } @@ -20,21 +22,10 @@ public override bool Execute() { try { - var hasher = HashAlgorithm.Create("MD5"); - byte[] checksum; - using (var file = File.OpenRead(SourceFile)) - { - checksum = hasher.ComputeHash(file); - } - var bldr = new StringBuilder(); - for ( int i=0; i < checksum.Length; i++ ) - { - bldr.Append(String.Format("{0:x2}", checksum[i])); - } var outputFile = SourceFile + ".MD5"; using (var writer = new StreamWriter(outputFile)) { - writer.Write(bldr.ToString()); + writer.Write(Compute(SourceFile)); } return true; } @@ -44,5 +35,21 @@ public override bool Execute() return false; } } + + public static string Compute(string filename) + { + byte[] checksumBytes; + using (var file = File.OpenRead(filename)) + { + checksumBytes = Hasher.ComputeHash(file); + } + var bldr = new StringBuilder(); + foreach (var b in checksumBytes) + { + bldr.AppendFormat("{0:x2}", b); + } + + return bldr.ToString(); + } } } diff --git a/Src/InstallValidator/InstallValidator.cs b/Src/InstallValidator/InstallValidator.cs new file mode 100644 index 0000000000..50f2ab3cfc --- /dev/null +++ b/Src/InstallValidator/InstallValidator.cs @@ -0,0 +1,107 @@ +// Copyright (c) 2019 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) + +using System.Diagnostics; +using System.IO; +using System.Security.Cryptography; +using System.Text; + +namespace SIL.InstallValidator +{ + public class InstallValidator + { + // ENHANCE (Hasso) 2019.07: look for extra files? + // ENHANCE (Hasso) 2019.07: option to catalog files that have already been installed (for testing against other upgrade scenarios) + public static void Main(string[] args) + { + if (args.Length == 0 || !File.Exists(args[0])) + { + // The user double-clicked (poor user won't see this), ran w/o args, or ran w/ invalid args. + Debug.WriteLine("SIL Installation Validator"); + Debug.WriteLine("Copyright (c) 2019 SIL International"); + Debug.WriteLine(string.Empty); + Debug.WriteLine("This program may be installed in the same directory as another SIL program,"); + Debug.WriteLine("but users should not use it. Its purpose is to help verify that the program"); + Debug.WriteLine(" was installed correctly."); + Debug.WriteLine("Usage:"); + Debug.WriteLine(" - Drop installerTestMetadata.csv on this exe to generate a report"); + Debug.WriteLine(" - InstallValidator.exe installerTestMetadata.csv [alternate report location]"); + Debug.WriteLine(" (for unit tests)"); + return; + } + + var logFile = SafeGetAt(args, 1) ?? Path.Combine(Path.GetTempPath(), "FlexInstallationReport.csv"); + + using (var expected = new StreamReader(args[0])) + using (var actual = new StreamWriter(logFile)) + { + actual.WriteLine("File, Result, Expected Version, Actual Version, Expected Date, Actual Date Modified (UTC)"); + expected.ReadLine(); // skip headers + string file; + while ((file = expected.ReadLine()) != null) + { + var info = file.Split(','); + if (info.Length < 2) + { + actual.WriteLine($"Bad input (or EOF), {file}"); + continue; + } + + var filePath = info[0].Trim(); + actual.Write(filePath); + var fullPath = Path.Combine(Directory.GetCurrentDirectory(), filePath); + if (!File.Exists(fullPath)) + { + actual.WriteLine(", is missing"); + continue; + } + + var expectedMd5 = info[1].Trim(); + var actualMd5 = ComputeMd5Sum(fullPath); + if (string.Equals(expectedMd5, actualMd5)) + { + actual.WriteLine(", was installed correctly"); + continue; + } + + var expectedVersion = SafeGetAt(info, 2); + var actualVersion = FileVersionInfo.GetVersionInfo(fullPath).FileVersion; + var expectedDate = SafeGetAt(info, 3); + var actualDate = File.GetLastWriteTimeUtc(fullPath); + actual.WriteLine( + $", incorrect file is present, {expectedVersion}, {actualVersion}, {expectedDate}, {actualDate:yyyy-MM-dd HH:mm:ss}"); + } + } + + // If we ran the program by dropping installerTestMetadata.csv, open the report using the default program + if (args.Length == 1) + { + Process.Start(logFile); + } + } + + private static string SafeGetAt(string[] arr, int index) + { + return arr.Length > index ? arr[index].Trim() : null; + } + + private static readonly HashAlgorithm Hasher = HashAlgorithm.Create("MD5"); + + public static string ComputeMd5Sum(string filename) + { + byte[] checksumBytes; + using (var file = File.OpenRead(filename)) + { + checksumBytes = Hasher.ComputeHash(file); + } + var bldr = new StringBuilder(); + foreach (var b in checksumBytes) + { + bldr.AppendFormat("{0:x2}", b); + } + + return bldr.ToString(); + } + } +} diff --git a/Src/InstallValidator/InstallValidator.csproj b/Src/InstallValidator/InstallValidator.csproj new file mode 100644 index 0000000000..8525793989 --- /dev/null +++ b/Src/InstallValidator/InstallValidator.csproj @@ -0,0 +1,99 @@ + + + + + Debug + AnyCPU + {EC1AD702-85A0-4431-823E-E3D3CB864E78} + Exe + SIL.InstallValidator + InstallValidator + v4.6.1 + 512 + true + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + ..\..\Output\Debug\ + DEBUG;TRACE + prompt + 4 + AnyCPU + true + + + pdbonly + true + ..\..\Output\Release\ + TRACE + prompt + 4 + AnyCPU + true + + + true + full + false + ..\..\Output\Debug\ + DEBUG;TRACE + prompt + 4 + AnyCPU + false + + + pdbonly + true + ..\..\Output\Release\ + TRACE + prompt + 4 + AnyCPU + false + + + + + + + + + + + + + + + + + + False + Microsoft .NET Framework 4.6.1 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + \ No newline at end of file diff --git a/Src/InstallValidator/InstallValidatorTests/InstallValidatorTests.cs b/Src/InstallValidator/InstallValidatorTests/InstallValidatorTests.cs new file mode 100644 index 0000000000..fdecf2097a --- /dev/null +++ b/Src/InstallValidator/InstallValidatorTests/InstallValidatorTests.cs @@ -0,0 +1,126 @@ +// Copyright (c) 2019 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) + +using System.Diagnostics; +using System.IO; +using System.Linq; +using NUnit.Framework; +using SIL.FieldWorks.Build.Tasks; +using SIL.TestUtilities; + +namespace SIL.InstallValidator +{ + [TestFixture] + public class InstallValidatorTests + { + private TemporaryFolder m_TestInstallDir; + + private string m_startingDirectory; + + private static int s_testCounter; + + private const string LogFileName = "metadataLog.csv"; + private const string ResultsFlieName = "resultsLog.csv"; + + [SetUp] + public void SetUp() + { + m_startingDirectory = Directory.GetCurrentDirectory(); + m_TestInstallDir = new TemporaryFolder($"InstallValidatorTests{s_testCounter++}"); + Directory.SetCurrentDirectory(m_TestInstallDir.Path); + } + + [TearDown] + public void TearDown() + { + Directory.SetCurrentDirectory(m_startingDirectory); // CD out of the directory before deleting it + m_TestInstallDir.Dispose(); + } + + [Test] + public void InstallValidatorTest() + { + // "install" some files + var currentDir = Directory.GetCurrentDirectory(); + + const string goodFileName = "correctly-installed-file.txt"; + var goodFilePath = Path.Combine(currentDir, goodFileName); + File.WriteAllText(goodFileName, "contents"); + + const string badFileName = "incorrectly-installed-file.txt"; + var badFilePath = Path.Combine(currentDir, badFileName); + File.WriteAllText(badFileName, "contents"); + + const string missingFileName = "not-installed-file.txt"; + var missingFilePath = Path.Combine(currentDir, missingFileName); + File.WriteAllText(missingFileName, "contents"); + + // record installed files' info in a CSV + new LogMetadata + { + Files = new[] { goodFilePath, badFilePath, missingFilePath }, + LogFile = LogFileName, + PathPrefixToDrop = $"{currentDir}/" + }.Execute(); + + // damage some installed files + File.Delete(missingFileName); + File.AppendAllText(badFileName, " are incorrect!"); + + // SUT + SystemUnderTest(); + + var results = File.ReadLines(ResultsFlieName).Select(line => line.Split(',')).ToDictionary(line => line[0]); + + Assert.Contains(goodFileName, results.Keys); + var result = results[goodFileName]; + Assert.AreEqual(2, result.Length, "correctly-installed files should have two columns in the report"); + StringAssert.EndsWith("installed correctly", result[1]); + + Assert.Contains(badFileName, results.Keys); + result = results[badFileName]; + Assert.GreaterOrEqual(result.Length, 2, "bad file report"); + StringAssert.Contains("incorrect", result[1]); + + Assert.Contains(missingFileName, results.Keys); + result = results[missingFileName]; + Assert.GreaterOrEqual(result.Length, 2, "missing file report"); + StringAssert.EndsWith("missing", result[1]); + + if (results.Count > 5) + { + LogInputAndOutputFiles(); + Assert.Fail("Too many lines in the report"); + } + } + + private void SystemUnderTest() + { + var sut = new Process + { + StartInfo = new ProcessStartInfo(Path.Combine(m_startingDirectory, "InstallValidator.exe"), $"{LogFileName} {ResultsFlieName}") + { + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true + } + }; + sut.Start(); + var error = sut.StandardError.ReadToEnd(); // wait for the process to complete + if (!string.IsNullOrWhiteSpace(error)) + { + LogInputAndOutputFiles(); + Assert.Fail(error); + } + } + + private void LogInputAndOutputFiles() + { + Debug.WriteLine("Input file:"); + Debug.WriteLine(File.ReadAllText(LogFileName)); + Debug.WriteLine("Output File:"); + Debug.WriteLine(File.ReadAllText(ResultsFlieName)); + } + } +} diff --git a/Src/InstallValidator/InstallValidatorTests/InstallValidatorTests.csproj b/Src/InstallValidator/InstallValidatorTests/InstallValidatorTests.csproj new file mode 100644 index 0000000000..12f5c9557b --- /dev/null +++ b/Src/InstallValidator/InstallValidatorTests/InstallValidatorTests.csproj @@ -0,0 +1,109 @@ + + + + Debug + AnyCPU + Library + SIL.InstallValidator + InstallValidatorTests + v4.6.1 + + + 3.5 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + {6F0B6512-FC59-401F-B1A1-37B8D95DCDEA} + + + true + full + false + ..\..\..\Output\Debug\ + DEBUG;TRACE + prompt + 4 + AnyCPU + + + none + true + ..\..\..\Output\Release\ + TRACE + prompt + 4 + AnyCPU + + + true + full + false + ..\..\..\Output\Debug\ + DEBUG;TRACE + prompt + 4 + AnyCPU + + + none + true + ..\..\..\Output\Release\ + TRACE + prompt + 4 + AnyCPU + + + + ..\..\..\Build\FwBuildTasks.dll + + + False + ..\..\..\Output\Debug\InstallValidator.exe + + + + ..\..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll + + + ..\..\..\Output\Debug\SIL.TestUtilities.dll + + + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + \ No newline at end of file diff --git a/Src/InstallValidator/Properties/AssemblyInfo.cs b/Src/InstallValidator/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..dfedff2aa0 --- /dev/null +++ b/Src/InstallValidator/Properties/AssemblyInfo.cs @@ -0,0 +1,21 @@ +// Copyright (c) 2019 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) + +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("SIL")] +[assembly: AssemblyProduct("Install Validator")] +[assembly: AssemblyCopyright("Copyright (c) 2019 SIL International")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +// Using a static version because it is not "part" of FieldWorks and will never need patching. +// Save users a few K on their patch downloads (we can always send them a new version if needed for diagnosis). +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")]