/// <summary> /// Performs a Browse invocation. /// </summary> /// <param name="input"></param> /// <param name="test"></param> /// <param name="arg"></param> /// <param name="cds"></param> /// <param name="stats"></param> /// <returns></returns> public static CdsBrowseSearchResults Browse(BrowseInput input, CdsSubTest test, CdsSubTestArgument arg, CpContentDirectory cds, CdsResult_BrowseStats stats) { CdsBrowseSearchResults results = new CdsBrowseSearchResults(); results.SetError(UPnPTestStates.Pass); results.ResultErrors = new ArrayList(); arg._TestGroup.AddEvent(LogImportance.Remark, test.Name, "\"" + test.Name + "\" about to do " + input.PrintBrowseParams() + "."); try { cds.Sync_Browse(input.ObjectID, input.BrowseFlag, input.Filter, input.StartingIndex, input.RequestedCount, input.SortCriteria, out results.Result, out results.NumberReturned, out results.TotalMatches, out results.UpdateID); } catch (UPnPInvokeException error) { results.InvokeError = error; } if (results.InvokeError == null) { arg._TestGroup.AddEvent(LogImportance.Remark, test.Name, "\"" + test.Name + "\" completed " + input.PrintBrowseParams() + " with no errors returned by the device."); } else { arg._TestGroup.AddEvent(LogImportance.Remark, test.Name, "\"" + test.Name + "\" completed " + input.PrintBrowseParams() + " with the device returning an error."); } stats.TotalBrowseRequests++; ArrayList branches = null; if (results.InvokeError == null) { try { if (results.Result != null) { if (results.Result != "") { bool schemaOK = CheckDidlLiteSchema(results.Result); if (schemaOK) { results.MediaObjects = branches = MediaBuilder.BuildMediaBranches(results.Result, typeof(MediaItem), typeof(MediaContainer), true); if (branches.Count != results.NumberReturned) { results.ResultErrors.Add(new CdsException(input.PrintBrowseParams() + " has the \"Result\" argument indicating the presence of " + branches.Count + " media objects but the request returned NumberReturned=" + results.NumberReturned + ".")); } if (input.BrowseFlag == CpContentDirectory.Enum_A_ARG_TYPE_BrowseFlag.BROWSEMETADATA) { if (branches.Count != 1) { results.ResultErrors.Add(new CdsException(input.PrintBrowseParams() + " has the \"Result\" argument indicating the presence of " + branches.Count + " media objects but the request should have only returned 1 media object.")); } } foreach (IUPnPMedia mobj in branches) { IMediaContainer imc = mobj as IMediaContainer; if (imc != null) { if (imc.CompleteList.Count > 0) { StringBuilder offendingList = new StringBuilder(); int offenses = 0; foreach (IUPnPMedia offending in imc.CompleteList) { if (offenses > 0) { offendingList.Append(","); } offendingList.AppendFormat("\"{0}\"", offending.ID); offenses++; } results.ResultErrors.Add(new CdsException(input.PrintBrowseParams() + " has the \"Result\" argument with a declared container (ID=\"" + imc.ID + "\") element that also includes its immediate children. Illegally declared media objects in the response are: " + offendingList.ToString())); } } } } } } } catch (Exception error2) { results.ResultErrors.Add(error2); if (results.MediaObjects == null) { results.MediaObjects = new ArrayList(); } } } // log any errors if ((results.InvokeError != null) || (results.ResultErrors.Count > 0)) { LogErrors(arg._TestGroup, test, input, "Browse", results.InvokeError, results.ResultErrors); results.SetError(UPnPTestStates.Failed); } return(results); }
/// <summary> /// Performs a Browse invocation. /// </summary> /// <param name="input"></param> /// <param name="test"></param> /// <param name="arg"></param> /// <param name="cds"></param> /// <param name="stats"></param> /// <returns></returns> public static CdsBrowseSearchResults Browse(BrowseInput input, CdsSubTest test, CdsSubTestArgument arg, CpContentDirectory cds, CdsResult_BrowseStats stats) { CdsBrowseSearchResults results = new CdsBrowseSearchResults(); results.SetError(UPnPTestStates.Pass); results.ResultErrors = new ArrayList(); arg._TestGroup.AddEvent(LogImportance.Remark, test.Name, "\""+test.Name+"\" about to do " + input.PrintBrowseParams()+ "."); try { cds.Sync_Browse(input.ObjectID, input.BrowseFlag, input.Filter, input.StartingIndex, input.RequestedCount, input.SortCriteria, out results.Result, out results.NumberReturned, out results.TotalMatches, out results.UpdateID); } catch (UPnPInvokeException error) { results.InvokeError = error; } if (results.InvokeError == null) { arg._TestGroup.AddEvent(LogImportance.Remark, test.Name, "\""+test.Name+"\" completed " + input.PrintBrowseParams()+ " with no errors returned by the device."); } else { arg._TestGroup.AddEvent(LogImportance.Remark, test.Name, "\""+test.Name+"\" completed " + input.PrintBrowseParams()+ " with the device returning an error."); } stats.TotalBrowseRequests++; ArrayList branches = null; if (results.InvokeError == null) { try { if (results.Result != null) { if (results.Result != "") { bool schemaOK = CheckDidlLiteSchema(results.Result); if (schemaOK) { results.MediaObjects = branches = MediaBuilder.BuildMediaBranches(results.Result, typeof (MediaItem), typeof(MediaContainer), true); if (branches.Count != results.NumberReturned) { results.ResultErrors.Add (new CdsException(input.PrintBrowseParams() + " has the \"Result\" argument indicating the presence of " +branches.Count+ " media objects but the request returned NumberReturned=" +results.NumberReturned+".")); } if (input.BrowseFlag == CpContentDirectory.Enum_A_ARG_TYPE_BrowseFlag.BROWSEMETADATA) { if (branches.Count != 1) { results.ResultErrors.Add (new CdsException(input.PrintBrowseParams() + " has the \"Result\" argument indicating the presence of " +branches.Count+ " media objects but the request should have only returned 1 media object.")); } } foreach (IUPnPMedia mobj in branches) { IMediaContainer imc = mobj as IMediaContainer; if (imc != null) { if (imc.CompleteList.Count > 0) { StringBuilder offendingList = new StringBuilder(); int offenses = 0; foreach (IUPnPMedia offending in imc.CompleteList) { if (offenses > 0) { offendingList.Append(","); } offendingList.AppendFormat("\"{0}\"", offending.ID); offenses++; } results.ResultErrors.Add (new CdsException(input.PrintBrowseParams() + " has the \"Result\" argument with a declared container (ID=\""+imc.ID+"\") element that also includes its immediate children. Illegally declared media objects in the response are: "+offendingList.ToString())); } } } } } } } catch (Exception error2) { results.ResultErrors.Add (error2); if (results.MediaObjects == null) { results.MediaObjects = new ArrayList(); } } } // log any errors if ((results.InvokeError != null) || (results.ResultErrors.Count > 0)) { LogErrors(arg._TestGroup, test, input, "Browse", results.InvokeError, results.ResultErrors); results.SetError(UPnPTestStates.Failed); } return results; }
/// <summary> /// Tests the container with BrowseDirectChildren and different ranges. /// </summary> /// <param name="c"></param> /// <param name="test"></param> /// <param name="arg"></param> /// <param name="cds"></param> /// <param name="stats"></param> /// <returns></returns> public static CdsBrowseSearchResults TestContainerRanges(IMediaContainer c, CdsSubTest test, CdsSubTestArgument arg, CpContentDirectory cds, CdsResult_BrowseStats stats) { CdsBrowseSearchResults r = new CdsBrowseSearchResults(); try { BrowseInput input = new BrowseInput(); input.BrowseFlag = CpContentDirectory.Enum_A_ARG_TYPE_BrowseFlag.BROWSEDIRECTCHILDREN; input.Filter = "*"; input.ObjectID = c.ID; input.SortCriteria = ""; input.StartingIndex = 0; input.RequestedCount = 0; if (c.CompleteList.Count != c.ChildCount) { throw new TestException("\""+test.Name+"\" has c.CompleteList.Count=" +c.CompleteList.Count+ " but c.ChildCount=" +c.ChildCount+ ".", c); } //assume the test will pass, but worsen the result when we find errors r.SetError(UPnPTestStates.Pass); // test starting index = 0 to c.ChildCount+1 // test requested count = 0 to c.ChildCoun+1 for (uint start = 0; start < c.ChildCount+1; start++) { for (uint requested = 0; requested < c.ChildCount+1; requested++) { uint start_requested = start+requested; bool doBrowse = false; int tenthCount = c.ChildCount / 10; int quarterCount = c.ChildCount / 4; if (quarterCount == 0) { quarterCount = 1; } if (tenthCount == 0) { tenthCount = 1; } if (start < LIMIT) { if ( (requested == 0) || (start_requested > c.ChildCount - LIMIT) ) { doBrowse = true; } } else if (start >= c.ChildCount - LIMIT) { if (start_requested < c.ChildCount+LIMIT) { doBrowse = true; } } else if ((start % quarterCount == 0) && (requested % tenthCount == 0)) { doBrowse = true; } if (doBrowse == false) { //stats.TotalBrowseRequests++; //arg.ActiveTests.UpdateTimeAndProgress(stats.TotalBrowseRequests * 300); } else { arg.ActiveTests.UpdateTimeAndProgress(stats.TotalBrowseRequests * 300); input.StartingIndex = start; input.RequestedCount = requested; CdsBrowseSearchResults br; br = Cds_BrowseAll.Browse(input, test, arg, cds, stats); if (br.WorstError >= UPnPTestStates.Failed) { if ( (input.StartingIndex < c.ChildCount) ) { throw new TerminateEarly("\"" + test.Name + "\" is terminating early because " +input.PrintBrowseParams()+ " returned with an error or had problems with the DIDL-Lite."); } else { arg._TestGroup.AddEvent(LogImportance.High, test.Name, "\"" + test.Name + "\": Warning: " +input.PrintBrowseParams()+ " returned an error."); r.SetError(UPnPTestStates.Warn); } } // check return values if (br.NumberReturned != br.MediaObjects.Count) { throw new TerminateEarly("\""+test.Name+"\" did a "+ input.PrintBrowseParams() + " and the number of media objects instantiated from the DIDL-Lite (instantiated=" +br.MediaObjects.Count+ ") does not match NumberReturned=" +br.NumberReturned+"."); } long expectedReturned; if (input.StartingIndex == 0) { if (input.RequestedCount == 0) { expectedReturned = c.ChildCount; } else if (input.RequestedCount > c.ChildCount) { expectedReturned = c.ChildCount; } else if (input.RequestedCount <= c.ChildCount) { expectedReturned = input.RequestedCount; } else { throw new TestException("\""+test.Name+"\" should not reach here.", null); } } else { if (input.RequestedCount == 0) { expectedReturned = c.ChildCount - input.StartingIndex; } else { expectedReturned = c.ChildCount - input.StartingIndex; if (expectedReturned > input.RequestedCount) { expectedReturned = input.RequestedCount; } } } if ((expectedReturned < 0) || (expectedReturned > c.ChildCount)) { throw new TestException("\""+test.Name+"\" did a " + input.PrintBrowseParams() + " and the expected number of media objects is invalid=" + expectedReturned + ".", br); } if (br.NumberReturned != expectedReturned) { throw new TerminateEarly("\""+test.Name+"\" did a "+ input.PrintBrowseParams() + " and NumberReturned=" +br.NumberReturned+ " but test expects " +expectedReturned+ " child objects according to results from a prerequisite test."); } if (br.TotalMatches != c.ChildCount) { throw new TerminateEarly("\""+test.Name+"\" did a "+ input.PrintBrowseParams() + " and TotalMatches=" +br.TotalMatches+ " but test found " +c.ChildCount+ " child objects in a prerequisite test."); } uint cUpdateID = 0; try { cUpdateID = (uint) c.Tag; } catch (Exception ce) { throw new TestException("\""+test.Name+"\" could not cast c.Tag into a uint value", null, ce); } if (br.UpdateID != cUpdateID) { throw new TerminateEarly("\""+test.Name+"\" did a "+ input.PrintBrowseParams() + " and UpdateID=" +br.UpdateID+ " but test expected=" +cUpdateID+ " as found in a prerequisite test."); } arg.TestGroup.AddEvent(LogImportance.Remark, test.Name, "\""+test.Name+"\" did a " +input.PrintBrowseParams()+ " and encountered no errors in the results."); arg.ActiveTests.UpdateTimeAndProgress(stats.TotalBrowseRequests * 300); } } } } catch (TerminateEarly te) { arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, test.Name + " is terminating early because of the following error: " + te.Message); r.SetError(UPnPTestStates.Failed); return r; } if (r.WorstError > UPnPTestStates.Warn) { throw new TestException("\"" + test.Name + "\" should not reach this code if the result is worse than " + UPnPTestStates.Warn.ToString() + ".", null); } return r; }
/// <summary> /// Tests the container with BrowseDirectChildren and different ranges. /// </summary> /// <param name="c"></param> /// <param name="test"></param> /// <param name="arg"></param> /// <param name="cds"></param> /// <param name="stats"></param> /// <returns></returns> public static CdsBrowseSearchResults TestContainerRanges(IMediaContainer c, CdsSubTest test, CdsSubTestArgument arg, CpContentDirectory cds, CdsResult_BrowseStats stats) { CdsBrowseSearchResults r = new CdsBrowseSearchResults(); try { BrowseInput input = new BrowseInput(); input.BrowseFlag = CpContentDirectory.Enum_A_ARG_TYPE_BrowseFlag.BROWSEDIRECTCHILDREN; input.Filter = "*"; input.ObjectID = c.ID; input.SortCriteria = ""; input.StartingIndex = 0; input.RequestedCount = 0; if (c.CompleteList.Count != c.ChildCount) { throw new TestException("\"" + test.Name + "\" has c.CompleteList.Count=" + c.CompleteList.Count + " but c.ChildCount=" + c.ChildCount + ".", c); } //assume the test will pass, but worsen the result when we find errors r.SetError(UPnPTestStates.Pass); // test starting index = 0 to c.ChildCount+1 // test requested count = 0 to c.ChildCoun+1 for (uint start = 0; start < c.ChildCount + 1; start++) { for (uint requested = 0; requested < c.ChildCount + 1; requested++) { uint start_requested = start + requested; bool doBrowse = false; int tenthCount = c.ChildCount / 10; int quarterCount = c.ChildCount / 4; if (quarterCount == 0) { quarterCount = 1; } if (tenthCount == 0) { tenthCount = 1; } if (start < LIMIT) { if ( (requested == 0) || (start_requested > c.ChildCount - LIMIT) ) { doBrowse = true; } } else if (start >= c.ChildCount - LIMIT) { if (start_requested < c.ChildCount + LIMIT) { doBrowse = true; } } else if ((start % quarterCount == 0) && (requested % tenthCount == 0)) { doBrowse = true; } if (doBrowse == false) { //stats.TotalBrowseRequests++; //arg.ActiveTests.UpdateTimeAndProgress(stats.TotalBrowseRequests * 300); } else { arg.ActiveTests.UpdateTimeAndProgress(stats.TotalBrowseRequests * 300); input.StartingIndex = start; input.RequestedCount = requested; CdsBrowseSearchResults br; br = Cds_BrowseAll.Browse(input, test, arg, cds, stats); if (br.WorstError >= UPnPTestStates.Failed) { if ( (input.StartingIndex < c.ChildCount) ) { throw new TerminateEarly("\"" + test.Name + "\" is terminating early because " + input.PrintBrowseParams() + " returned with an error or had problems with the DIDL-Lite."); } else { arg._TestGroup.AddEvent(LogImportance.High, test.Name, "\"" + test.Name + "\": Warning: " + input.PrintBrowseParams() + " returned an error."); r.SetError(UPnPTestStates.Warn); } } // check return values if (br.NumberReturned != br.MediaObjects.Count) { throw new TerminateEarly("\"" + test.Name + "\" did a " + input.PrintBrowseParams() + " and the number of media objects instantiated from the DIDL-Lite (instantiated=" + br.MediaObjects.Count + ") does not match NumberReturned=" + br.NumberReturned + "."); } long expectedReturned; if (input.StartingIndex == 0) { if (input.RequestedCount == 0) { expectedReturned = c.ChildCount; } else if (input.RequestedCount > c.ChildCount) { expectedReturned = c.ChildCount; } else if (input.RequestedCount <= c.ChildCount) { expectedReturned = input.RequestedCount; } else { throw new TestException("\"" + test.Name + "\" should not reach here.", null); } } else { if (input.RequestedCount == 0) { expectedReturned = c.ChildCount - input.StartingIndex; } else { expectedReturned = c.ChildCount - input.StartingIndex; if (expectedReturned > input.RequestedCount) { expectedReturned = input.RequestedCount; } } } if ((expectedReturned < 0) || (expectedReturned > c.ChildCount)) { throw new TestException("\"" + test.Name + "\" did a " + input.PrintBrowseParams() + " and the expected number of media objects is invalid=" + expectedReturned + ".", br); } if (br.NumberReturned != expectedReturned) { throw new TerminateEarly("\"" + test.Name + "\" did a " + input.PrintBrowseParams() + " and NumberReturned=" + br.NumberReturned + " but test expects " + expectedReturned + " child objects according to results from a prerequisite test."); } if (br.TotalMatches != c.ChildCount) { throw new TerminateEarly("\"" + test.Name + "\" did a " + input.PrintBrowseParams() + " and TotalMatches=" + br.TotalMatches + " but test found " + c.ChildCount + " child objects in a prerequisite test."); } uint cUpdateID = 0; try { cUpdateID = (uint)c.Tag; } catch (Exception ce) { throw new TestException("\"" + test.Name + "\" could not cast c.Tag into a uint value", null, ce); } if (br.UpdateID != cUpdateID) { throw new TerminateEarly("\"" + test.Name + "\" did a " + input.PrintBrowseParams() + " and UpdateID=" + br.UpdateID + " but test expected=" + cUpdateID + " as found in a prerequisite test."); } arg.TestGroup.AddEvent(LogImportance.Remark, test.Name, "\"" + test.Name + "\" did a " + input.PrintBrowseParams() + " and encountered no errors in the results."); arg.ActiveTests.UpdateTimeAndProgress(stats.TotalBrowseRequests * 300); } } } } catch (TerminateEarly te) { arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, test.Name + " is terminating early because of the following error: " + te.Message); r.SetError(UPnPTestStates.Failed); return(r); } if (r.WorstError > UPnPTestStates.Warn) { throw new TestException("\"" + test.Name + "\" should not reach this code if the result is worse than " + UPnPTestStates.Warn.ToString() + ".", null); } return(r); }