public override UPnPTestStates Run(ICollection otherSubTests, CdsSubTestArgument arg) { CpContentDirectory CDS = this.GetCDS(arg._Device); _Details = new CdsResult_BrowseFilterRangeSort(); this._TestState = UPnPTestStates.Running; arg._TestGroup.AddEvent(LogImportance.Remark, this.Name, "\"" + this.Name + "\" started."); // get the results from the prerequisite tests CdsResult_BrowseFilter FILTER_RESULTS = null; CdsResult_BrowseRange RANGE_RESULTS = null; CdsResult_BrowseSortCriteria SORT_RESULTS = null; try { foreach (ISubTest preTest in otherSubTests) { if (preTest.Name == this.PRE_FILTER.Name) { FILTER_RESULTS = preTest.Details as CdsResult_BrowseFilter; } else if (preTest.Name == this.PRE_RANGE.Name) { RANGE_RESULTS = preTest.Details as CdsResult_BrowseRange; } else if (preTest.Name == this.PRE_SORT.Name) { SORT_RESULTS = preTest.Details as CdsResult_BrowseSortCriteria; } } if (FILTER_RESULTS == null) { throw new TestException(this._Name + " requires that the \"" + this.PRE_FILTER.Name + "\" test be run as a prerequisite. The results from that test cannot be obtained.", otherSubTests); } if (RANGE_RESULTS == null) { throw new TestException(this._Name + " requires that the \"" + this.PRE_RANGE.Name + "\" test be run as a prerequisite. The results from that test cannot be obtained.", otherSubTests); } if (SORT_RESULTS == null) { throw new TestException(this._Name + " requires that the \"" + this.PRE_SORT.Name + "\" test be run as a prerequisite. The results from that test cannot be obtained.", otherSubTests); } } catch (Exception e) { throw new TestException(this._Name + " requires that the \"" + this.PRE_FILTER.Name + "\" and \"" + this.PRE_RANGE + "\" and \"" + this.PRE_SORT + "\" tests be run before. An error occurred when attempting to obtain the results of those prerequisites.", otherSubTests, e); } UPnPTestStates state = this._TestState; CdsResult_BrowseAll BROWSE_ALL = FILTER_RESULTS.BrowseAllResults; if (BROWSE_ALL.LargestContainer == null) { throw new TestException(new Cds_BrowseAll().Name + " failed to find the container with the most child objects. " + this._Name + " requires this value.", BROWSE_ALL); } if (BROWSE_ALL.MostMetadata == null) { throw new TestException(new Cds_BrowseAll().Name + " failed to find the media object with the most metadata. " + this._Name + " requires this value.", BROWSE_ALL); } if (SORT_RESULTS.SortFields == null) { throw new TestException(new Cds_BrowseAll().Name + " failed to find the sortable fields. " + this._Name + " requires this value.", SORT_RESULTS); } int max = Math.Max(FILTER_RESULTS.Filters.Count, BROWSE_ALL.LargestContainer.ChildCount); max = Math.Max(max, SORT_RESULTS.SortFields.Count); this._Details.ExpectedTotalBrowseRequests = max + 1; this._Details.TotalBrowseRequests = 0; this._ExpectedTestingTime = this._Details.ExpectedTotalBrowseRequests * 900; arg.ActiveTests.UpdateTimeAndProgress(this._Details.TotalBrowseRequests * 900); state = UPnPTestStates.Pass; for (int i = 0; i <= max; i++) { ArrayList filterList = new ArrayList(); for (int j = 0; j < i; j++) { if (j < FILTER_RESULTS.Filters.Count) { filterList.Add(FILTER_RESULTS.Filters[j]); } else { break; } } string filterSettings = Cds_BrowseTest.GetCSVString(filterList); uint range = (uint)i; if (range > BROWSE_ALL.LargestContainer.ChildCount) { range = (uint)BROWSE_ALL.LargestContainer.ChildCount; } ArrayList sortList = new ArrayList(); for (int j = 0; j < i; j++) { if (j < SORT_RESULTS.SortFields.Count) { sortList.Add(SORT_RESULTS.SortFields[j]); } else { break; } } BrowseInput input = new BrowseInput(); input.ObjectID = BROWSE_ALL.LargestContainer.ID; input.BrowseFlag = CpContentDirectory.Enum_A_ARG_TYPE_BrowseFlag.BROWSEDIRECTCHILDREN; input.Filter = filterSettings; input.RequestedCount = range; input.SortCriteria = Cds_BrowseSortCriteria.GetSortCriteriaString(sortList, i); input.StartingIndex = 0; this._ExpectedTestingTime = (max) * 900; arg.ActiveTests.UpdateTimeAndProgress(this._Details.TotalBrowseRequests * 900); CdsBrowseSearchResults br = Cds_BrowseTest.Browse(input, this, arg, CDS, _Details); MediaContainer original = (MediaContainer)BROWSE_ALL.LargestContainer; uint ignored; IList expectedResults; expectedResults = original.BrowseSorted(0, input.RequestedCount, new MediaSorter(true, input.SortCriteria), out ignored); try { if (br.WorstError <= UPnPTestStates.Warn) { if (br.MediaObjects.Count != expectedResults.Count) { throw new TerminateEarly(input.PrintBrowseParams() + " returned DIDL-Lite that declared " + br.MediaObjects.Count + " media objects but test expected " + expectedResults.Count.ToString() + " media objects as found in a prerequisite test."); } bool warnOrder = false; for (int ri = 0; ri < br.MediaObjects.Count; ri++) { IUPnPMedia resultObj = (IUPnPMedia)br.MediaObjects[ri]; IUPnPMedia originalObj = (IUPnPMedia)expectedResults[ri]; if (resultObj.ID != originalObj.ID) { warnOrder = true; } foreach (string propName in resultObj.Properties.PropertyNames) { if (filterList.Contains(propName) == false) { if ( (propName != T[_DC.title]) && (propName != T[_UPNP.Class]) ) { StringBuilder msg = new StringBuilder(); msg.AppendFormat("\"" + this.Name + "\" is terminating early because {0} returned DIDL-Lite with \"{1}\" metadata when it should not have done so.", input.PrintBrowseParams(), propName); throw new TerminateEarly(msg.ToString()); } } } } int expectedCount = i; if ((i == 0) || (i > BROWSE_ALL.LargestContainer.ChildCount)) { expectedCount = BROWSE_ALL.LargestContainer.ChildCount; } if (br.MediaObjects.Count != expectedCount) { StringBuilder msg = new StringBuilder(); msg.AppendFormat("\"{0}\" did a {1} and the DIDL-Lite result only has {2} media objects when {3} media objects were expected.", this.Name, input.PrintBrowseParams(), br.MediaObjects.Count, expectedCount); msg.AppendFormat(".\r\nDIDL-Lite ==> {0}", br.Result); throw new TerminateEarly(msg.ToString()); } if (warnOrder) { /* * ArrayList missingResults = new ArrayList(); * * foreach (IUPnPMedia em in expectedResults) * { * bool found = false; * foreach (IUPnPMedia fm in br.MediaObjects) * { * if (em.ID == fm.ID) * { * found = true; * break; * } * } * * if (found == false) * { * missingResults.Add(em); * } * } * * if (missingResults.Count > 0) * { * state = UPnPTestStates.Failed; * StringBuilder msg = new StringBuilder(); * msg.AppendFormat("\"{0}\" did a {1} and the result is missing media objects.", this.Name, input.PrintBrowseParams()); * msg.Append("\r\nExpected order of IDs: "); * int z = 0; * foreach (IUPnPMedia em in expectedResults) * { * if (z > 0) * { * msg.Append(","); * } * msg.AppendFormat("\"{0}\"", em.ID); * z++; * } * msg.Append("\r\nDIDL-Lite result's order of IDs: "); * z = 0; * foreach (IUPnPMedia em in br.MediaObjects) * { * if (z > 0) * { * msg.Append(","); * } * msg.AppendFormat("\"{0}\"", em.ID); * z++; * } * msg.AppendFormat(".\r\nDIDL-Lite ==> {0}", br.Result); * throw new TerminateEarly(msg.ToString()); * } * else */ { StringBuilder msg = new StringBuilder(); msg.AppendFormat("WARNING: \"{0}\" did a {1} and got items in a different order. Target CDS either has an error in its sorting logic, or sorting logic intentionally deviates from test.", this.Name, input.PrintBrowseParams()); msg.Append("\r\nExpected order of IDs: "); int z = 0; foreach (IUPnPMedia em in expectedResults) { if (z > 0) { msg.Append(","); } msg.AppendFormat("\"{0}\"", em.ID); z++; } msg.Append("\r\nDIDL-Lite result's order of IDs: "); z = 0; foreach (IUPnPMedia em in br.MediaObjects) { if (z > 0) { msg.Append(","); } msg.AppendFormat("\"{0}\"", em.ID); z++; } msg.AppendFormat(".\r\nDIDL-Lite ==> {0}", br.Result); arg._TestGroup.AddEvent(LogImportance.Medium, this.Name, msg.ToString()); state = UPnPTestStates.Warn; } } } else { throw new TerminateEarly("\"" + this.Name + "\" is terminating early because " + input.PrintBrowseParams() + " returned with an error or had problems with the DIDL-Lite."); } } catch (TerminateEarly te) { arg._TestGroup.AddEvent(LogImportance.Critical, this.Name, "\"" + this.Name + "\" terminating early. Reason ==> " + te.Message); state = UPnPTestStates.Failed; break; } } // finish up logging this._TestState = state; StringBuilder sb = new StringBuilder(); sb.AppendFormat("\"{0}\" completed", this.Name); if (this._TestState <= UPnPTestStates.Running) { throw new TestException("\"" + this.Name + "\" must have a pass/warn/fail result.", this._TestState); } switch (this._TestState) { case UPnPTestStates.Pass: sb.Append(" successfully."); break; case UPnPTestStates.Warn: sb.Append(" with warnings."); break; case UPnPTestStates.Failed: sb.Append(" with a failed result."); break; } arg._TestGroup.AddResult(sb.ToString()); if (this._TestState <= UPnPTestStates.Warn) { if (_Details.TotalBrowseRequests != _Details.ExpectedTotalBrowseRequests) { throw new TestException("TotalBrowseRequests=" + _Details.TotalBrowseRequests.ToString() + " ExpectedTotal=" + _Details.ExpectedTotalBrowseRequests.ToString(), _Details); } } arg._TestGroup.AddEvent(LogImportance.Remark, this.Name, this.Name + " finished."); return(this._TestState); }
public override UPnPTestStates Run(ICollection otherSubTests, CdsSubTestArgument arg) { CpContentDirectory CDS = this.GetCDS(arg._Device); _Details = new CdsResult_BrowseSortCriteria(); this._TestState = UPnPTestStates.Running; arg._TestGroup.AddEvent(LogImportance.Remark, this.Name, "\"" + this.Name + "\" started."); // get the results from the prerequisite tests CdsResult_BrowseAll BROWSE_RESULTS = null; CdsResult_GetSortCapabilities SORTCAPS = null; try { foreach (ISubTest preTest in otherSubTests) { if (preTest.Name == this.PRE_BROWSEALL.Name) { BROWSE_RESULTS = preTest.Details as CdsResult_BrowseAll; } else if (preTest.Name == this.PRE_SORTCAPS.Name) { SORTCAPS = preTest.Details as CdsResult_GetSortCapabilities; } } if (BROWSE_RESULTS == null) { throw new TestException(this._Name + " requires that the \"" + this.PRE_BROWSEALL.Name + "\" test be run as a prerequisite. The results from that test cannot be obtained.", otherSubTests); } if (SORTCAPS == null) { throw new TestException(this._Name + " requires that the \"" + this.PRE_SORTCAPS.Name + "\" test be run as a prerequisite. The results from that test cannot be obtained.", otherSubTests); } } catch (Exception e) { throw new TestException(this._Name + " requires that the \"" + this.PRE_BROWSEALL.Name + "\" and \"" + this.PRE_SORTCAPS + "\" tests be run before. An error occurred when attempting to obtain the results of those prerequisites.", otherSubTests, e); } _Details.BrowseAllResults = BROWSE_RESULTS; _Details.SortCapsResults = SORTCAPS; UPnPTestStates state = this._TestState; if (BROWSE_RESULTS.LargestContainer == null) { throw new TestException(this.PRE_BROWSEALL.Name + " failed to find the container with the most child objects. " + this._Name + " requires this value.", BROWSE_RESULTS); } MediaContainer MC = BROWSE_RESULTS.LargestContainer as MediaContainer; if (MC == null) { throw new TestException(this.PRE_BROWSEALL.Name + " has the largest container as type \"" + BROWSE_RESULTS.LargestContainer.GetType().ToString() + "\" when \"" + this.Name + "\" requires \"" + typeof(MediaContainer).ToString() + "\".", BROWSE_RESULTS); } ArrayList sortFields = new ArrayList(); if (SORTCAPS.SortCapabilities == "") { //arg.TestGroup.AddEvent(LogImportance.Remark, this.Name, "\""+this.Name+"\" has no sorting capabilities."); } else if (SORTCAPS.SortCapabilities == "*") { sortFields = (ArrayList)BROWSE_RESULTS.PropertyNames.Clone(); } else { sortFields.AddRange(GetSortFields(SORTCAPS.SortCapabilities)); } _Details.ExpectedTotalBrowseRequests = 0; _Details.SortFields = sortFields; int fieldCount = sortFields.Count; IList childList = BROWSE_RESULTS.LargestContainer.CompleteList; _Details.ExpectedTotalBrowseRequests = 0; //fieldCount * fieldCount * fieldCount; uint inc = (uint)(childList.Count / 3); int firstInc = (fieldCount / 3); if (firstInc == 0) { firstInc = 1; } for (int numFields = 0; numFields < fieldCount; numFields++) { for (int first = 0; first < fieldCount; first += firstInc) { //for (uint i=0; i < childList.Count; i+=inc) { _Details.ExpectedTotalBrowseRequests++; } } } // add 1 for an unsorted browse _Details.ExpectedTotalBrowseRequests++; //multiply by 2 because we have 2 rounds to check for consistency in ordered results _Details.ExpectedTotalBrowseRequests *= 2; //calculate time this._ExpectedTestingTime = _Details.ExpectedTotalBrowseRequests * 900; arg.ActiveTests.UpdateTimeAndProgress(0); if (state <= UPnPTestStates.Running) { state = UPnPTestStates.Pass; try { ArrayList round2 = new ArrayList(); //perform the standard unsorted browse BrowseInput input = new BrowseInput(); input.BrowseFlag = CpContentDirectory.Enum_A_ARG_TYPE_BrowseFlag.BROWSEDIRECTCHILDREN; input.StartingIndex = 0; input.ObjectID = MC.ID; input.RequestedCount = 0; input.Filter = "*"; input.SortCriteria = ""; CdsBrowseSearchResults br = Browse(input, this, arg, CDS, _Details); Round2 r2 = new Round2(); r2.Input = (BrowseInput)input.Clone(); r2.PreviousResult = br; round2.Add(r2); for (int numFields = 0; numFields < fieldCount; numFields++) { for (int first = 0; first < fieldCount; first += firstInc) { ArrayList sortSettings = GetSortSettings(sortFields, first, first); input.SortCriteria = GetSortCriteriaString(sortSettings, numFields + first); arg.ActiveTests.UpdateTimeAndProgress(_Details.TotalBrowseRequests * 900); uint ignored; //use this sorter for to determine the expected order of the media objects IMediaSorter sorter = new MediaSorter(true, input.SortCriteria); IList expectedSorted = MC.BrowseSorted(0, 0, sorter, out ignored); br = Browse(input, this, arg, CDS, _Details); arg.ActiveTests.UpdateTimeAndProgress(_Details.TotalBrowseRequests * 900); this.CompareResultsAgainstExpected(br, expectedSorted, ref state, arg, input, false); r2 = new Round2(); r2.Input = (BrowseInput)input.Clone(); r2.PreviousResult = br; round2.Add(r2); } } //do round2 - check for consistency in results foreach (Round2 r in round2) { br = Browse(r.Input, this, arg, CDS, _Details); arg.ActiveTests.UpdateTimeAndProgress(_Details.TotalBrowseRequests * 900); this.CompareResultsAgainstExpected(br, r.PreviousResult.MediaObjects, ref state, arg, r.Input, true); } } catch (TerminateEarly te) { string reason = "\"" + this.Name + "\" terminating early. Reason => " + te.Message; arg._TestGroup.AddEvent(LogImportance.Critical, this.Name, reason); state = UPnPTestStates.Failed; } } // finish up logging this._TestState = state; StringBuilder sb = new StringBuilder(); sb.AppendFormat("\"{0}\" completed", this.Name); if (this._TestState <= UPnPTestStates.Running) { throw new TestException("\"" + this.Name + "\" must have a pass/warn/fail result.", this._TestState); } switch (this._TestState) { case UPnPTestStates.Pass: sb.Append(" successfully."); break; case UPnPTestStates.Warn: sb.Append(" with warnings."); break; case UPnPTestStates.Failed: sb.Append(" with a failed result."); break; } arg._TestGroup.AddResult(sb.ToString()); if (this._TestState <= UPnPTestStates.Warn) { if (_Details.TotalBrowseRequests != _Details.ExpectedTotalBrowseRequests) { throw new TestException("TotalBrowseRequests=" + _Details.TotalBrowseRequests.ToString() + " ExpectedTotal=" + _Details.ExpectedTotalBrowseRequests.ToString(), _Details); } } arg._TestGroup.AddEvent(LogImportance.Remark, this.Name, sb.ToString()); return(this._TestState); }