public void VersionCheck_Services_Correct() { // set a fake assembly version for testing purposes var av = new Version(3, 3, 3, 3); var servicesInfo = new SnComponentInfo { AssemblyVersion = av, SupportedVersion = av }; Assert.IsTrue(RepositoryVersionInfo.IsComponentAllowed(servicesInfo, av)); // it is NOT allowed to have an assembly with an older version than the installed component Assert.IsFalse(RepositoryVersionInfo.IsComponentAllowed(servicesInfo, new Version(av.Major, av.Minor, av.Build + 1, av.Revision))); Assert.IsFalse(RepositoryVersionInfo.IsComponentAllowed(servicesInfo, new Version(av.Major, av.Minor + 1, av.Build, av.Revision))); Assert.IsFalse(RepositoryVersionInfo.IsComponentAllowed(servicesInfo, new Version(av.Major + 1, av.Minor, av.Build, av.Revision))); // This is the edge case where the assembly version's _revision_ number (the 4th one) // is different than the component version, which is allowed. Assert.IsTrue(RepositoryVersionInfo.IsComponentAllowed(servicesInfo, new Version(av.Major, av.Minor, av.Build, av.Revision - 1))); Assert.IsTrue(RepositoryVersionInfo.IsComponentAllowed(servicesInfo, new Version(av.Major, av.Minor, av.Build, av.Revision + 1))); // This should be false, because the supported version is set to the current version that means // the component can work only with the same version as the component version in the assembly. Assert.IsFalse(RepositoryVersionInfo.IsComponentAllowed(servicesInfo, new Version(av.Major, av.Minor, av.Build - 1))); Assert.IsFalse(RepositoryVersionInfo.IsComponentAllowed(servicesInfo, new Version(av.Major, av.Minor - 1, av.Build))); Assert.IsFalse(RepositoryVersionInfo.IsComponentAllowed(servicesInfo, new Version(av.Major - 1, av.Minor, av.Build))); }
public void Packaging_EzRelease_CreateComponentInfo_SupportedVersionNull() { var componentName = "TestComponent-1"; var component = new TestComponent(componentName, null); var componentInfo = SnComponentInfo.Create(component); var thisVersion = TypeHandler.GetVersion(this.GetType().Assembly); Assert.AreEqual(componentName, componentInfo.ComponentId); Assert.AreEqual(thisVersion, componentInfo.AssemblyVersion); Assert.AreEqual(thisVersion, componentInfo.SupportedVersion); }
public void Packaging_EzRelease_CreateComponentInfo_SupportedVersionLessThanThisVersion() { var thisVersion = TypeHandler.GetVersion(this.GetType().Assembly); var supportedVersion = thisVersion.Minor == 0 ? new Version(thisVersion.Major - 1, 9, thisVersion.MajorRevision) : new Version(thisVersion.Major, thisVersion.Minor - 1, thisVersion.Build); var supportedVersionString = supportedVersion.ToString(); var componentName = "TestComponent-1"; var component = new TestComponent(componentName, supportedVersionString, false); var componentInfo = SnComponentInfo.Create(component); Assert.AreEqual(componentName, componentInfo.ComponentId); Assert.AreEqual(thisVersion, componentInfo.AssemblyVersion); Assert.AreEqual(supportedVersion, componentInfo.SupportedVersion); Assert.IsFalse(componentInfo.IsComponentAllowed.Invoke(null)); }
public void Packaging_EzRelease_CreateComponentInfo_SupportedVersionGreaterThanThisVersion() { var thisVersion = TypeHandler.GetVersion(this.GetType().Assembly); var supportedVersion = new Version(thisVersion.Major, thisVersion.Minor + 1, 0); var supportedVersionString = supportedVersion.ToString(); var componentName = "TestComponent-1"; var component = new TestComponent(componentName, supportedVersionString, false); try { var componentInfo = SnComponentInfo.Create(component); Assert.Fail(); } catch (ApplicationException) { // do nothing } }
private bool RunComponent(SnComponentInfo component) { try { RepositoryVersionInfo.CheckComponentVersions(new[] { component }, true); return(true); } catch (InvalidOperationException e) { if (e.Message.Contains("component is missing.")) { return(false); } throw; } catch (ApplicationException e) { if (e.Message.Contains("Component and assembly version mismatch.")) { return(false); } throw; } }
internal static Dictionary <Version, PackagingResult> ExecuteAssemblyPatches(SnComponentInfo assemblyComponent, RepositoryStartSettings settings = null) { var patchResults = new Dictionary <Version, PackagingResult>(); // If there is no installed component for this id, skip patching. var installedComponent = RepositoryVersionInfo.Instance.Components.FirstOrDefault(c => c.ComponentId == assemblyComponent.ComponentId); if (installedComponent == null) { return(patchResults); } // check which db version is supported by the assembly if (assemblyComponent.SupportedVersion == null || assemblyComponent.SupportedVersion <= installedComponent.Version) { return(patchResults); } // Supported version in the assembly is higher than // the physical version: there should be a patch. if (!(assemblyComponent.Patches?.Any() ?? false)) { throw new InvalidOperationException($"Missing patch for component {installedComponent.ComponentId}. " + $"Installed version is {installedComponent.Version}. " + $"The assembly requires at least version {assemblyComponent.SupportedVersion}."); } foreach (var patch in assemblyComponent.Patches) { // this variable is refreshed in every cycle if (installedComponent == null) { break; } if (patch.MinVersion > patch.MaxVersion || patch.MaxVersion > patch.Version) { // the patch version numbers are the responsibility of the developer of the component SnLog.WriteWarning( $"Patch {patch.Version} for component {assemblyComponent.ComponentId} cannot be executed because it contains invalid version numbers.", properties: new Dictionary <string, object> { { "MinVersion", patch.MinVersion }, { "MaxVersion", patch.MaxVersion } }); continue; } if (!string.IsNullOrEmpty(patch.Contents) && patch.Execute != null) { // ambigous patch definition SnLog.WriteWarning( $"Patch {patch.Version} for component {assemblyComponent.ComponentId} cannot be executed because it contains multiple patch definitions."); continue; } // check if the patch is relevant for the currently installed component version if (patch.MinVersion > installedComponent.Version || patch.MinVersionIsExclusive && patch.MinVersion == installedComponent.Version || patch.MaxVersion < installedComponent.Version || patch.MaxVersionIsExclusive && patch.MaxVersion == installedComponent.Version) { continue; } PackagingResult patchResult; try { if (patch.Contents?.StartsWith("<?xml", StringComparison.InvariantCultureIgnoreCase) ?? false) { // execute manifest patch patchResult = ExecutePatch(patch.Contents, settings); } else if (patch.Execute != null) { // execute code patch patch.Execute(new PatchContext { Settings = settings }); // save the new package info manually based on the patch version number Storage.SavePackageAsync(new Package { ComponentId = assemblyComponent.ComponentId, ComponentVersion = patch.Version, ExecutionResult = ExecutionResult.Successful, PackageType = PackageType.Patch }, CancellationToken.None).GetAwaiter().GetResult(); patchResult = new PackagingResult { NeedRestart = false, Successful = true, Terminated = false, Errors = 0 }; } else { //TODO: handle other patch formats (resource or filesystem path) // unknown patch format patchResult = new PackagingResult { NeedRestart = false, Successful = false, Terminated = false, Errors = 0 }; } } catch (Exception ex) { SnLog.WriteException(ex, $"Error during patch execution for component {assemblyComponent.ComponentId}. Patch target version: {patch.Version}."); throw; } patchResults[patch.Version] = patchResult; // reload installedComponent = RepositoryVersionInfo.Instance.Components.FirstOrDefault(c => c.ComponentId == assemblyComponent.ComponentId); } return(patchResults); }