public static global::System.Xml.Schema.XmlSchemaComplexType GetTypedDataSetSchema(global::System.Xml.Schema.XmlSchemaSet xs) { ReqTable ds = new ReqTable(); global::System.Xml.Schema.XmlSchemaComplexType type = new global::System.Xml.Schema.XmlSchemaComplexType(); global::System.Xml.Schema.XmlSchemaSequence sequence = new global::System.Xml.Schema.XmlSchemaSequence(); global::System.Xml.Schema.XmlSchemaAny any = new global::System.Xml.Schema.XmlSchemaAny(); any.Namespace = ds.Namespace; sequence.Items.Add(any); type.Particle = sequence; global::System.Xml.Schema.XmlSchema dsSchema = ds.GetSchemaSerializable(); if (xs.Contains(dsSchema.TargetNamespace)) { global::System.IO.MemoryStream s1 = new global::System.IO.MemoryStream(); global::System.IO.MemoryStream s2 = new global::System.IO.MemoryStream(); try { global::System.Xml.Schema.XmlSchema schema = null; dsSchema.Write(s1); for (global::System.Collections.IEnumerator schemas = xs.Schemas(dsSchema.TargetNamespace).GetEnumerator(); schemas.MoveNext(); ) { schema = ((global::System.Xml.Schema.XmlSchema)(schemas.Current)); s2.SetLength(0); schema.Write(s2); if ((s1.Length == s2.Length)) { s1.Position = 0; s2.Position = 0; for (; ((s1.Position != s1.Length) && (s1.ReadByte() == s2.ReadByte())); ) { ; } if ((s1.Position == s1.Length)) { return type; } } } } finally { if ((s1 != null)) { s1.Close(); } if ((s2 != null)) { s2.Close(); } } } xs.Add(dsSchema); return type; }
public static global::System.Xml.Schema.XmlSchemaComplexType GetTypedTableSchema(global::System.Xml.Schema.XmlSchemaSet xs) { global::System.Xml.Schema.XmlSchemaComplexType type = new global::System.Xml.Schema.XmlSchemaComplexType(); global::System.Xml.Schema.XmlSchemaSequence sequence = new global::System.Xml.Schema.XmlSchemaSequence(); ReqTable ds = new ReqTable(); global::System.Xml.Schema.XmlSchemaAny any1 = new global::System.Xml.Schema.XmlSchemaAny(); any1.Namespace = "http://www.w3.org/2001/XMLSchema"; any1.MinOccurs = new decimal(0); any1.MaxOccurs = decimal.MaxValue; any1.ProcessContents = global::System.Xml.Schema.XmlSchemaContentProcessing.Lax; sequence.Items.Add(any1); global::System.Xml.Schema.XmlSchemaAny any2 = new global::System.Xml.Schema.XmlSchemaAny(); any2.Namespace = "urn:schemas-microsoft-com:xml-diffgram-v1"; any2.MinOccurs = new decimal(1); any2.ProcessContents = global::System.Xml.Schema.XmlSchemaContentProcessing.Lax; sequence.Items.Add(any2); global::System.Xml.Schema.XmlSchemaAttribute attribute1 = new global::System.Xml.Schema.XmlSchemaAttribute(); attribute1.Name = "namespace"; attribute1.FixedValue = ds.Namespace; type.Attributes.Add(attribute1); global::System.Xml.Schema.XmlSchemaAttribute attribute2 = new global::System.Xml.Schema.XmlSchemaAttribute(); attribute2.Name = "tableTypeName"; attribute2.FixedValue = "RequirementDataTable"; type.Attributes.Add(attribute2); type.Particle = sequence; global::System.Xml.Schema.XmlSchema dsSchema = ds.GetSchemaSerializable(); if (xs.Contains(dsSchema.TargetNamespace)) { global::System.IO.MemoryStream s1 = new global::System.IO.MemoryStream(); global::System.IO.MemoryStream s2 = new global::System.IO.MemoryStream(); try { global::System.Xml.Schema.XmlSchema schema = null; dsSchema.Write(s1); for (global::System.Collections.IEnumerator schemas = xs.Schemas(dsSchema.TargetNamespace).GetEnumerator(); schemas.MoveNext(); ) { schema = ((global::System.Xml.Schema.XmlSchema)(schemas.Current)); s2.SetLength(0); schema.Write(s2); if ((s1.Length == s2.Length)) { s1.Position = 0; s2.Position = 0; for (; ((s1.Position != s1.Length) && (s1.ReadByte() == s2.ReadByte())); ) { ; } if ((s1.Position == s1.Length)) { return type; } } } } finally { if ((s1 != null)) { s1.Close(); } if ((s2 != null)) { s2.Close(); } } } xs.Add(dsSchema); return type; }
//validate derived requirement private bool ValidateDerivedRequirement(ReqTable.RequirementRow derivedReq) { //ignore original requirement without derivation. if (derivedReq.IsDerivedNull() || string.IsNullOrEmpty(derivedReq.Derived.Trim())) { return false; } //////////////////////if ((deltaScopes.Count > 0 && !deltaScopes.Contains(derivedReq.Delta))) //////////////////////{ ////////////////////// return false; //////////////////////} bool validateResult = true; if (!requirementsToVerify.ContainsKey(derivedReq.REQ_ID)) { if (!validationErrors.ContainsKey(derivedReq.REQ_ID)) { //error: derived requirement cannot be informative if (informativeReqs.Contains(derivedReq.REQ_ID)) { validationErrors.Add(derivedReq.REQ_ID, RSValidationRules.DERIVEDREQISINFORMATIVE); } //error: derived requirement cannot be out-of-scope else if (scopeRules[ReportingParameters.outScopeRule].Contains(derivedReq.Scope.ToLower())) { validationErrors.Add(derivedReq.REQ_ID, RSValidationRules.DERIVEDREQOUTOFSCOPE); } //error: derived requirement is deleted, non-testable or unverified. else if (string.Compare(derivedReq.Verification, VerificationValues.DELETED) == 0) { validationErrors.Add(derivedReq.REQ_ID, RSValidationRules.DERIVEDREQNOTTESTABLE); validateResult = false; } else if (string.Compare(derivedReq.Verification, VerificationValues.NONTESTABLE) == 0 || string.Compare(derivedReq.Verification, VerificationValues.UNVERIFIED) == 0) { //derived requirement can only be tast case or adapter. validationErrors.Add(derivedReq.REQ_ID, RSValidationRules.DERIVEDREQNOTTESTABLE); } } } return validateResult; }
//validate original requirement private bool ValidateOriginalRequirement(ReqTable.RequirementRow derivedReq, string originalId) { bool isLegal = true; //error: cannot derive from deleted if (requirementsDeleted.ContainsKey(originalId)) { if (!validationErrors.ContainsKey(derivedReq.REQ_ID)) { validationErrors.Add(derivedReq.REQ_ID, RSValidationRules.DERIVEFROMDELETED); } isLegal = false; } //check the original requirement is normative and testable. else if (requirementsNotToVerify.ContainsKey(originalId)) { //error: cannot derive from informative if (informativeReqs.Contains(originalId)) { //we ignore informative+unverified requirement, //and not count this kind of requirement to coverage. if (!validationErrors.ContainsKey(derivedReq.REQ_ID) && string.Compare(RequirementVerifications[originalId], VerificationValues.UNVERIFIED, true) != 0) { derivedFromInformativeReqs.Add(derivedReq.REQ_ID); validationErrors.Add(derivedReq.REQ_ID, RSValidationRules.DERIVEFROMINFORMATIVE); } } } else { switch (RequirementVerifications[originalId]) { case VerificationValues.UNVERIFIED: { //warning: cannot derive from normative, unverified. //should still add to derived requirement table. if (!validationWarnings.ContainsKey(derivedReq.REQ_ID)) { validationWarnings.Add(derivedReq.REQ_ID, RSValidationRules.DERIVEFROMUNVERIFIED); } break; } default: { //do nothing break; } } } return isLegal; }
/// <summary> /// compute requirement using new rule /// </summary> /// <param name="row">The requirement row contians scope column</param> private void ComputRequirementV2(ReqTable.RequirementRow row) { List<string> ltStrings = new List<string>(); if (row.IsScopeNull() && !row.IsActorNull()) { throw new InvalidOperationException("Using Actor and Scope together is not supported."); } row.Scope = row.Scope.Trim(); string keyword = "none"; if (string.Compare(row.Scope, keyword, true) == 0) { throw new InvalidOperationException( string.Format("'None' keyword should not be the value of scope in requirement {0}", row.REQ_ID)); } if (scopeRules[ReportingParameters.inScopeRule].Contains(row.Scope.ToLower()) && scopeRules[ReportingParameters.outScopeRule].Contains(row.Scope.ToLower())) { throw new InvalidOperationException( string.Format("Value {0} for InScope and OutOfScope parameters is duplicated.", row.Scope)); } else if (!scopeRules[ReportingParameters.inScopeRule].Contains(row.Scope.ToLower()) && !scopeRules[ReportingParameters.outScopeRule].Contains(row.Scope.ToLower())) { throw new InvalidOperationException( string.Format("Unexpected scope value in Requirement {0}.", row.REQ_ID)); } else if (scopeRules[ReportingParameters.inScopeRule].Contains(row.Scope.ToLower())) { //in-scope requirement if (string.Compare("Normative", row.IsNormative, true) == 0) { switch (row.Verification) { case VerificationValues.ADAPTER: case VerificationValues.TESTCASE: case VerificationValues.UNVERIFIED: { if ((deltaScopes.Count > 0 && !deltaScopes.Contains(row.Delta))) { if (row.IsDerivedNull() || string.IsNullOrEmpty(row.Derived)) { //original requirement is out of delta scope ltStrings.Add(row.Description); ltStrings.Add(row.Doc_Sect); ltStrings.Add(row.Scope); requirementsNotToVerify.Add(row.REQ_ID, ltStrings); oriReqOutOfDeltaScope.Add(row.REQ_ID); } else { //in-scope, normative, testable requirement ltStrings.Add(row.Description); ltStrings.Add(row.Doc_Sect); ltStrings.Add(row.Scope); requirementsToVerify.Add(row.REQ_ID, ltStrings); } } else { ltStrings.Add(row.Description); ltStrings.Add(row.Doc_Sect); ltStrings.Add(row.Scope); requirementsToVerify.Add(row.REQ_ID, ltStrings); } break; } default: { //in-scope, normative, un-testable requirement ltStrings.Add(row.Description); ltStrings.Add(row.Doc_Sect); ltStrings.Add(row.Scope); requirementsNotToVerify.Add(row.REQ_ID, ltStrings); break; } } } else { //informative requirement should be ignore. ltStrings.Add(row.Description); ltStrings.Add(row.Doc_Sect); ltStrings.Add(row.Scope); requirementsNotToVerify.Add(row.REQ_ID, ltStrings); informativeReqs.Add(row.REQ_ID); } } else { if (string.Compare("Informative", row.IsNormative, true) == 0) { informativeReqs.Add(row.REQ_ID); } ltStrings.Add(row.Description); ltStrings.Add(row.Doc_Sect); ltStrings.Add(row.Scope); //out of scope requirement should not to verify requirementsNotToVerify.Add(row.REQ_ID, ltStrings); if (string.Compare(VerificationValues.ADAPTER, row.Verification, true) == 0 || string.Compare(VerificationValues.TESTCASE, row.Verification, true) == 0) { //out of scope requirement should not mark as testable. if (!validationErrors.ContainsKey(row.REQ_ID)) { validationErrors.Add(row.REQ_ID, RSValidationRules.OUTOFSCOPEISTESTABLE); } } } }
private void Load(IList<string> reqFilenames) { try { ReqTable requirementTable = null; ReqTable tempTable = new ReqTable(); foreach (string reqfile in reqFilenames) { if (requirementTable == null) { requirementTable = new ReqTable(); requirementTable.ReadXml(XmlReader.Create(reqfile, new XmlReaderSettings() { XmlResolver = null })); } else { tempTable.ReadXml(XmlReader.Create(reqfile, new XmlReaderSettings() { XmlResolver = null })); requirementTable.Merge(tempTable); tempTable.Clear(); } } tempTable.Dispose(); bool newVersion = false; // Now requirementTable contains all requirement tables from user's input // to simplify the coding, ReportingTool assumes all of them are user's required. foreach (ReqTable.RequirementRow row in requirementTable.Requirement) { //remove all start or end spacese. row.REQ_ID = row.REQ_ID.Trim(); row.Verification = row.Verification.Trim(); //translate the blank to new for delta value if (row.IsDeltaNull() || string.IsNullOrEmpty(row.Delta.Trim())) { row.Delta = "new"; } else { row.Delta = row.Delta.ToLower().Trim(); } //cache all requirements and verifications. this.reqVerifications.Add(row.REQ_ID, row.Verification); if (string.Compare(row.Verification, VerificationValues.DELETED, true) == 0) { List<string> ltStrings = new List<string>(); ltStrings.Add(row.Description); ltStrings.Add(row.Doc_Sect); ltStrings.Add(row.Scope); requirementsDeleted.Add(row.REQ_ID, ltStrings); continue; } TotalCount++; if (row.IsActorNull() && row.IsScopeNull()) { throw new InvalidOperationException( String.Format("Column Actor or Scope is expected at {0}", row.REQ_ID)); } if (!row.IsScopeNull() && TotalCount == 1) { //estimate RS version from the first requirement newVersion = true; } if (newVersion) { ComputRequirementV2(row); } else { ComputRequirementV1(row); } } //make sure there is no duplicated id in RS Req_Id column. MakeSureNoDuplicateId(); if (newVersion) { //compute derived requirements and original requirements foreach (ReqTable.RequirementRow row in requirementTable.Requirement) { if (ValidateDerivedRequirement(row)) { ComputeDerivedRequirement(row); } } } //filter the requirement which only derived from informative requirement(s) foreach(string derivedId in derivedFromInformativeReqs) { DerivedRequirement derivedReq = derivedRequirements[derivedId]; foreach (string originalId in derivedReq.OriginalReqs) { if (!informativeReqs.Contains(originalId)) { validationErrors.Remove(derivedId); } } } foreach (string invalidOriReq in oriReqOutOfDeltaScope) { RemoveDerivedRequirmentRelationship(invalidOriReq); } requirementTable.Dispose(); //find the loop in the requirement table and throw exception when loops exist. FindLoop(); } catch (Exception e) { throw new InvalidOperationException( String.Format("[ERROR] Unable to get requirement data from specified requirement table files. Details:\r\n{0}", e.Message + e.StackTrace)); } }
/// <summary> /// compute requirement using old rule /// </summary> /// <param name="row">The requirement row contains actor column</param> private void ComputRequirementV1(ReqTable.RequirementRow row) { List<string> ltStrings = new List<string>(); if (row.IsActorNull() && !row.IsScopeNull()) { throw new InvalidOperationException("Using Actor and Scope together is not supported."); } if (scopeMode) { throw new InvalidOperationException("Scope is not supported in old version of RS"); } if (deltaScopes.Count > 0) { throw new InvalidOperationException("Delta scope is not supported in old version of RS"); } if ( (String.Compare(row.IsNormative, "Normative", false) == 0) && (String.Compare(row.Actor, "Client", false) != 0) && (String.Compare(row.Verification, "Non-testable", false) != 0) ) { // all requirements that are normative & non-client & testable ltStrings.Add(row.Description); ltStrings.Add(row.Doc_Sect); ltStrings.Add(row.Scope); requirementsToVerify.Add(row.REQ_ID, ltStrings); } else { ltStrings.Add(row.Description); ltStrings.Add(row.Doc_Sect); ltStrings.Add(row.Scope); requirementsNotToVerify.Add(row.REQ_ID, ltStrings); } }
private void ComputeDerivedRequirement(ReqTable.RequirementRow row) { if (row.IsDerivedNull() || String.Compare(row.Verification, VerificationValues.DELETED, true) == 0) { return; } string derivedReqs = row.Derived; if (!string.IsNullOrEmpty(derivedReqs.Trim())) { string[] originalReqs = derivedReqs.Split(new char[] { ',' }); if (originalReqs != null) { foreach (string originalReq in originalReqs) { if (string.IsNullOrEmpty(originalReq.Trim())) { continue; } string[] terms = originalReq.Split(new char[] { ':' }); if (terms == null || terms.Length > 2) { throw new FormatException( string.Format("The format of derived text {0} in Requirement {1}:\"{2}\" is not correct," + "the correct format should be Req_ID plus :i :p or :c as suffix.", originalReq, row.REQ_ID, row.Description)); } string originalId = terms[0].Trim(); if (string.IsNullOrEmpty(originalId)) { throw new FormatException( string.Format("The originalID cannot be null or empty in Requirement {1}:\"{2}\"", row.REQ_ID, row.Description)); } //check the original requirement exists. originalId = GetRequirementId(originalId, true); if (string.IsNullOrEmpty(originalId)) { if (!validationErrors.ContainsKey(row.REQ_ID)) { validationErrors.Add(row.REQ_ID, string.Format(RSValidationRules.DERIVEFROMNONEXIST, terms[0])); } continue; } if (terms.Length == 2) { //treat "R1: " as default if (string.IsNullOrEmpty(terms[1].Trim())) { AddDerivedRequirement("i", originalId, row); } else { AddDerivedRequirement(terms[1].Trim(), originalId, row); } } else { //default type is :i AddDerivedRequirement("i", originalId, row); } } } } }
//build the graph of derived requirements. private void AddDerivedRequirement(string type, string originalId, ReqTable.RequirementRow row) { if (!ValidateOriginalRequirement(row, originalId)) { //error occurs, should not be added to build derived graph. return; } //add original requirement id to the current requirement's original id list. if (!derivedRequirements.ContainsKey(row.REQ_ID)) { DerivedRequirement derivedReq = new DerivedRequirement(row.REQ_ID, CoveredStatus.Unverified); derivedReq.AddOriginalRequirement(originalId); derivedRequirements.Add(row.REQ_ID, derivedReq); } else { if (!derivedRequirements[row.REQ_ID].OriginalReqs.Contains(originalId)) { DerivedRequirement derivedReq = derivedRequirements[row.REQ_ID]; derivedReq.AddOriginalRequirement(originalId); derivedRequirements[row.REQ_ID] = derivedReq; } } //add all derived requirements for current requirement //to the derived dictionary of original requirement switch (type.ToLower()) { case "i": AddDerived(originalId, row, DerivedType.Inferred); break; case "p": AddDerived(originalId, row, DerivedType.Partial); break; case "c": AddDerived(originalId, row, DerivedType.Cases); break; default: throw new FormatException( string.Format("Unexpected derived type \"{0}\" is found in derived text in Requirement {1}:\"{2}\"," + "the type must be one of i, c or p.", type, row.REQ_ID, row.Description)); } }
private void AddDerived(string originalId, ReqTable.RequirementRow row, DerivedType type) { if (!derivedRequirements.ContainsKey(originalId)) { DerivedRequirement originalReq = new DerivedRequirement(originalId, CoveredStatus.Unverified); originalReq.AddDerivedRequirement(row.REQ_ID, type); derivedRequirements.Add(originalId, originalReq); } else { if (!derivedRequirements[originalId].DerivedReqs.ContainsKey(row.REQ_ID)) { DerivedRequirement originalReq = derivedRequirements[originalId]; originalReq.AddDerivedRequirement(row.REQ_ID, type); derivedRequirements[originalId] = originalReq; } } }
private void Load(IList <string> reqFilenames) { try { ReqTable requirementTable = null; ReqTable tempTable = new ReqTable(); foreach (string reqfile in reqFilenames) { if (requirementTable == null) { requirementTable = new ReqTable(); requirementTable.ReadXml(XmlReader.Create(reqfile, new XmlReaderSettings() { XmlResolver = null })); } else { tempTable.ReadXml(XmlReader.Create(reqfile, new XmlReaderSettings() { XmlResolver = null })); requirementTable.Merge(tempTable); tempTable.Clear(); } } tempTable.Dispose(); bool newVersion = false; // Now requirementTable contains all requirement tables from user's input // to simplify the coding, ReportingTool assumes all of them are user's required. foreach (ReqTable.RequirementRow row in requirementTable.Requirement) { //remove all start or end spacese. row.REQ_ID = row.REQ_ID.Trim(); row.Verification = row.Verification.Trim(); //translate the blank to new for delta value if (row.IsDeltaNull() || string.IsNullOrEmpty(row.Delta.Trim())) { row.Delta = "new"; } else { row.Delta = row.Delta.ToLower().Trim(); } //cache all requirements and verifications. this.reqVerifications.Add(row.REQ_ID, row.Verification); if (string.Compare(row.Verification, VerificationValues.DELETED, true) == 0) { List <string> ltStrings = new List <string>(); ltStrings.Add(row.Description); ltStrings.Add(row.Doc_Sect); ltStrings.Add(row.Scope); requirementsDeleted.Add(row.REQ_ID, ltStrings); continue; } TotalCount++; if (row.IsActorNull() && row.IsScopeNull()) { throw new InvalidOperationException( String.Format("Column Actor or Scope is expected at {0}", row.REQ_ID)); } if (!row.IsScopeNull() && TotalCount == 1) { //estimate RS version from the first requirement newVersion = true; } if (newVersion) { ComputRequirementV2(row); } else { ComputRequirementV1(row); } } //make sure there is no duplicated id in RS Req_Id column. MakeSureNoDuplicateId(); if (newVersion) { //compute derived requirements and original requirements foreach (ReqTable.RequirementRow row in requirementTable.Requirement) { if (ValidateDerivedRequirement(row)) { ComputeDerivedRequirement(row); } } } //filter the requirement which only derived from informative requirement(s) foreach (string derivedId in derivedFromInformativeReqs) { DerivedRequirement derivedReq = derivedRequirements[derivedId]; foreach (string originalId in derivedReq.OriginalReqs) { if (!informativeReqs.Contains(originalId)) { validationErrors.Remove(derivedId); } } } foreach (string invalidOriReq in oriReqOutOfDeltaScope) { RemoveDerivedRequirmentRelationship(invalidOriReq); } requirementTable.Dispose(); //find the loop in the requirement table and throw exception when loops exist. FindLoop(); } catch (Exception e) { throw new InvalidOperationException( String.Format("[ERROR] Unable to get requirement data from specified requirement table files. Details:\r\n{0}", e.Message + e.StackTrace)); } }