/// <summary> /// Run the specified test script. /// </summary> protected Collection <PSObject> RunPowerShellTest(string script) { Collection <PSObject> output; if (string.IsNullOrEmpty(script)) { throw new ArgumentException(nameof(script)); } using (PowerShell powershell = PowerShell.Create()) { powershell.AddScript("$Error.clear()"); powershell.AddScript($"Write-Debug \"Current directory: {AppDomain.CurrentDomain.BaseDirectory}\""); powershell.AddScript($"Write-Debug \"Current executing assembly: {Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)}\""); powershell.AddScript($"cd \"{AppDomain.CurrentDomain.BaseDirectory}\""); powershell.AddScript($"Import-Module \"{Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "PartnerCenter.psm1")}\""); powershell.AddScript($"Import-Module \"{Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ScenarioTests\\Common.ps1")}\""); powershell.AddScript($"Import-Module \"{Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"ScenarioTests\\{GetType().Name}.ps1")}\""); string test = GetType().Name; powershell.AddScript("$VerbosePreference='Continue'"); powershell.AddScript("$DebugPreference='Continue'"); powershell.AddScript("$ErrorActionPreference='Stop'"); powershell.AddScript(script); try { powershell.Runspace.Events.Subscribers.Clear(); output = powershell.Invoke(); if (powershell.Streams.Error.Count > 0) { throw new RuntimeException( $"Test failed due to a non-empty error stream. First error: {FormatErrorRecord(powershell.Streams.Error[0])}{(powershell.Streams.Error.Count > 0 ? "Check the error stream in the test log for additional errors." : "")}"); } return(output); } finally { powershell.Streams.Error.Clear(); } } }
IEnumerable <StdfRecord> InternalGetAllRecords() { //set this in case the last time we ended in seek mode using (IStdfStreamScope streamScope = _StreamManager.GetScope()) { try { _Stream = new RewindableByteStream(streamScope.Stream); //read the FAR to get endianness var endian = Endian.Little; var far = new byte[6]; if (_Stream.Read(far, 6) < 6) { yield return(new StartOfStreamRecord { Endian = Endian.Unknown, ExpectedLength = _Stream.Length }); yield return(new FormatErrorRecord { Message = Resources.FarReadError, Recoverable = false }); yield return(new EndOfStreamRecord()); yield break; } endian = far[4] < 2 ? Endian.Big : Endian.Little; var stdfVersion = far[5]; var length = (endian == Endian.Little ? far[0] : far[1]); if (length != 2) { yield return(new StartOfStreamRecord { Endian = endian, ExpectedLength = _Stream.Length }); yield return(new FormatErrorRecord { Message = Resources.FarLengthError, Recoverable = false }); yield return(new EndOfStreamRecord { Offset = 2 }); yield break; } //validate record type if (far[2] != 0) { yield return(new StartOfStreamRecord { Endian = endian, ExpectedLength = _Stream.Length }); yield return(new FormatErrorRecord { Offset = 2, Message = Resources.FarRecordTypeError, Recoverable = false }); yield return(new EndOfStreamRecord { Offset = 6 }); yield break; } //validate record type if (far[3] != 10) { yield return(new StartOfStreamRecord { Endian = endian, ExpectedLength = _Stream.Length }); yield return(new FormatErrorRecord { Offset = 3, Message = Resources.FarRecordSubTypeError, Recoverable = false }); yield return(new EndOfStreamRecord { Offset = 3 }); yield break; } //OK we're satisfied, let's go yield return(new StartOfStreamRecord() { Endian = endian, ExpectedLength = _Stream.Length }); yield return(new StdfReader.Records.V4.Far() { CpuType = far[4], StdfVersion = far[5] }); //flush the memory _Stream.Flush(); //now we have the FAR out of the way, and we can blow through the rest. while (true) { var position = _Stream.Offset; //read a record header RecordHeader?header = _Stream.ReadHeader(endian); //null means we hit EOS if (header == null) { if (!_Stream.PastEndOfStream) { //Something's wrong. We know the offset is rewound //to the begining of the header. If there's still //data, we're corrupt yield return(new CorruptDataRecord() { Offset = position, //TODO: leverage the data in the stream. //we know we've hit the end, so we can just dump //the remaining memoized data CorruptData = _Stream.DumpRemainingData(), Recoverable = false }); yield return(new FormatErrorRecord() { Message = Resources.EOFInHeader, Recoverable = false, Offset = position }); } yield return(new EndOfStreamRecord() { Offset = _Stream.Offset }); yield break; } var contents = new byte[header.Value.Length]; int read = _Stream.Read(contents, contents.Length); if (read < contents.Length) { //rewind to the beginning of the record (read bytes + the header) _Stream.Rewind((int)(_Stream.Offset - position)); yield return(new CorruptDataRecord() { Offset = position, CorruptData = _Stream.DumpRemainingData(), Recoverable = false }); yield return(new FormatErrorRecord() { Message = Resources.EOFInRecordContent, Recoverable = false, Offset = position }); } else { StdfRecord r; if (header.Value.RecordType == PTR) { r = PTR.Converter(contents, endian); } else if (header.Value.RecordType == MPR) { r = MPR.Converter(contents, endian); } else if (header.Value.RecordType == FTR) { r = FTR.Converter(contents, endian); } else if (header.Value.RecordType == ATR) { r = ATR.Converter(contents, endian); } else if (header.Value.RecordType == MIR) { r = MIR.Converter(contents, endian); } else if (header.Value.RecordType == MRR) { r = MRR.Converter(contents, endian); } else if (header.Value.RecordType == PCR) { r = PCR.Converter(contents, endian); } else if (header.Value.RecordType == HBR) { r = HBR.Converter(contents, endian); } else if (header.Value.RecordType == SBR) { r = SBR.Converter(contents, endian); } else if (header.Value.RecordType == PMR) { r = PMR.Converter(contents, endian); } else if (header.Value.RecordType == PGR) { r = PGR.Converter(contents, endian); } else if (header.Value.RecordType == PLR) { r = PLR.Converter(contents, endian); } else if (header.Value.RecordType == RDR) { r = RDR.Converter(contents, endian); } else if (header.Value.RecordType == SDR) { r = SDR.Converter(contents, endian); } else if (header.Value.RecordType == WIR) { r = WIR.Converter(contents, endian); } else if (header.Value.RecordType == WRR) { r = WRR.Converter(contents, endian); } else if (header.Value.RecordType == WCR) { r = WCR.Converter(contents, endian); } else if (header.Value.RecordType == PIR) { r = PIR.Converter(contents, endian); } else if (header.Value.RecordType == PRR) { r = PRR.Converter(contents, endian); } else if (header.Value.RecordType == TSR) { r = TSR.Converter(contents, endian); } else if (header.Value.RecordType == BPS) { r = BPS.Converter(contents, endian); } else if (header.Value.RecordType == EPS) { r = EPS.Converter(contents, endian); } else if (header.Value.RecordType == GDR) { r = GDR.Converter(contents, endian); } else if (header.Value.RecordType == DTR) { r = DTR.Converter(contents, endian); } else { r = new FormatErrorRecord(); } //StdfRecord r = header.Value.RecordType.Converter(contents, endian); if (r.GetType() != typeof(UnknownRecord)) { //it converted, so update our last known position //TODO: We should think about: //* how to indicate corruption within the record boundaries //* enabling filteres to set the last known offset (to allow valid unknown records to pass through) // * This could possible be done by allowing filters access to Flush or the dump functionality. _Stream.Flush(); } r.Offset = position; yield return(r); } } } finally { //set stream to null so we're not holding onto it _Stream = null; } } }