private void PreserveTestCheck() { var safeGraph = OriginalDcrGraphs[0]; for (int i = 0; i < OriginalDcrGraphs.Count; i++) { if (i + 1 >= OriginalDcrGraphs.Count) { break; } var next = OriginalDcrGraphs[i + 1]; var tc = safeGraph.IsTransparent(next); var tn = next.IsTransparent(safeGraph); if (tc.Item1 == null && tc.Item2 == null && tn.Item1 == null && tn.Item2 == null) { var rawDcr = safeGraph.EditWindowString + " \r\n " + next.EditWindowString; safeGraph = new DcrGraph(rawDcr, new List <string>(), rawDcr, "MergedTestPreserved"); } else { if (tc.Item1 != null || tc.Item2 != null) { PreserveTests.Add(tc); } if (tn.Item1 != null || tn.Item2 != null) { PreserveTests.Add(tn); } } } }
public bool IsSafe(DcrGraph safeForDcrGraph) { //acyclic var dependencyGraph = this.BuildDependencyGraph(); var cycleChecker = new CycleChecker(); var cycle = cycleChecker.ExistsCycleConditionMilestone(dependencyGraph); var cycleResponse = cycleChecker.ExistsCycleResponse(dependencyGraph); if (cycle != null || cycleResponse != null) { return(false); } // no include, exclude or response to any activity if (dependencyGraph.Any(x => x._relationsOutgoing.Any(y => y.Type == Relation.RelationType.Include || y.Type == Relation.RelationType.Exclude || y.Type == Relation.RelationType.Response))) { return(false); } // np-hard? Check any outgoing condition/milestone reachable if (dependencyGraph.Any(x => x._relationsOutgoing.Any(y => (y.Type == Relation.RelationType.Condition || y.Type == Relation.RelationType.Milestone) && !ReachableFromTo(y.From, y.To, safeForDcrGraph)))) { return(false); } return(true); }
public void TakeEventLocalActivities(DcrGraph graphToMerge) { var sharedActivities = graphToMerge.Activities.Where(x => Activities.Exists(y => y.Id.Equals(x.Id))).ToList(); foreach (var sharedActivity in sharedActivities) { var localActivity = Activities.First(x => x.Id.Equals(sharedActivity.Id)); localActivity.Excluded = sharedActivity.Excluded || localActivity.Excluded; localActivity.Pending = sharedActivity.Pending || localActivity.Pending; localActivity.Executed = sharedActivity.Executed || localActivity.Executed; foreach (var relation in sharedActivity._relationsIncoming) { // from activity must exist in the local graph. The relation must not already exist. if (Activities.Exists(x => x.Id.Equals(relation.From.Id)) && !localActivity._relationsIncoming.Any(x => x.Type.Equals(relation.Type) && x.From.Id.Equals(relation.From.Id))) { var localFrom = Activities.First(x => x.Id.Equals(relation.From.Id)); localActivity._relationsIncoming.Add(new Relation(localFrom, localActivity, (int)relation.Type)); } } foreach (var relation in sharedActivity._relationsOutgoing) { // "to" activity must exist in the local graph. The relation must not already exist. if (Activities.Exists(x => x.Id.Equals(relation.To.Id)) && !localActivity._relationsOutgoing.Exists(x => x.Type.Equals(relation.Type) && x.From.Id.Equals(relation.From.Id))) { var localTo = Activities.First(x => x.Id.Equals(relation.To.Id)); localActivity._relationsOutgoing.Add(new Relation(localActivity, localTo, (int)relation.Type)); } } } }
private void CreateFullMerge() { var fullMergeRawDcr = ""; var allStrictActivities = new List <string>(); foreach (var dcrGraph in DcrGraphsToMerge) { fullMergeRawDcr += dcrGraph.EditWindowString + " \r\n\r\n "; allStrictActivities.AddRange(dcrGraph.StrictActivities); } DcrGraphFullMerge = new DcrGraph(fullMergeRawDcr, allStrictActivities, fullMergeRawDcr, "Full merge graph"); }
private bool ReachableFromTo(Activity from, Activity to, DcrGraph dcrGraph) { var testGraph = new DcrGraph(dcrGraph.EditWindowString, new List <string>(), dcrGraph.EditWindowString, dcrGraph.Name); var testFrom = testGraph.Activities.First(x => x.Id.Equals(from.Id)); var testTo = testGraph.Activities.First(x => x.Id.Equals(to.Id)); var executed = testFrom.TryExecute(); if (!executed) { return(false); } executed = testTo.TryExecute(); return(executed); }
private DcrGraph CreateXE(DcrGraph dcrGraph, Activity e) { var graphWithNoExcludeToActivityBeingTested = new DcrGraph(dcrGraph.EditWindowString, new List <string>(), dcrGraph.EditWindowString, "graphWithNoRelationsToActivityBeingTested"); var perhapsSafeActivity = graphWithNoExcludeToActivityBeingTested.Activities.Where(x => x._relationsOutgoing.Any(y => y.To.Id.Equals(e.Id) && y.Type == Relation.RelationType.Exclude)).ToList(); foreach (var activity1 in perhapsSafeActivity) { activity1._relationsOutgoing.Remove(activity1._relationsOutgoing.First(x => x.Type == Relation.RelationType.Exclude && x.To.Id.Equals(e.Id))); } return(graphWithNoExcludeToActivityBeingTested); }
private void PerformEventLocelMergeFromGraph(int index) { var startGraph = new DcrGraph(DcrGraphsToMerge[index].EditWindowString, DcrGraphsToMerge[index].StrictActivities, DcrGraphsToMerge[index].EditWindowString, DcrGraphsToMerge[index].Name); startGraph.StoredTraces = DcrGraphsToMerge[index].StoredTraces; for (int i = 0; i < DcrGraphsToMerge.Count; i++) { if (i == index) { continue; } var graphToMerge = DcrGraphsToMerge[i]; startGraph.TakeEventLocalActivities(graphToMerge); } DcrGraphEventLocalMerges.Add(startGraph); }
/// <summary> /// Null if transparent, otherwise return first relation that breaks. /// </summary> /// <param name="dcrGraph"></param> /// <returns></returns> public Tuple <Activity, Relation> IsTransparent(DcrGraph dcrGraph) { var dcrstring = EditWindowString + "\r\n" + dcrGraph.EditWindowString; var mergedGraph = new DcrGraph(dcrstring, new List <string>(), dcrstring, "tempMerge"); var newRelations = new List <Relation>(); foreach (var newRelation in dcrGraph._relations) { if (RelationExists(newRelation)) { continue; } newRelations.Add(newRelation); } foreach (var mergedActivity in mergedGraph.Activities) { var oldActivity = Activities.FirstOrDefault(x => x.Id.Equals(mergedActivity.Id)); //preserve marking if (oldActivity != null && oldActivity.Excluded != mergedActivity.Excluded && oldActivity.Pending != mergedActivity.Pending && oldActivity.Executed != mergedActivity.Executed) { return(new Tuple <Activity, Relation>(mergedActivity, null)); } // no new pending if (mergedActivity.Pending) { return(new Tuple <Activity, Relation>(mergedActivity, null)); } } foreach (var newRelation in newRelations) { switch (newRelation.Type) { case Relation.RelationType.Include: // not between old if (Activities.Any(x => x.Id.Equals(newRelation.From.Id)) && Activities.Any(x => x.Id.Equals(newRelation.To.Id))) { return(new Tuple <Activity, Relation>(newRelation.From, newRelation)); } //no old to new //if(Activities.Any(x => x.Id.Equals(newRelation.From.Id)) && !Activities.Any(x => x.Id.Equals(newRelation.To.Id))) return new Tuple<Activity, Relation>(newRelation.From, newRelation); // Includes to old must exists beforehand //if (Activities.Any(x => x.Id.Equals(newRelation.To.Id)) && !_relations.Any(x => x.Type == Relation.RelationType.Include && x.From.Id.Equals(newRelation.From.Id) && x.To.Id.Equals(newRelation.To.Id))) return new Tuple<Activity, Relation>(newRelation.From, newRelation); break; case Relation.RelationType.Exclude: // not between old if (Activities.Any(x => x.Id.Equals(newRelation.From.Id)) && Activities.Any(x => x.Id.Equals(newRelation.To.Id))) { return(new Tuple <Activity, Relation>(newRelation.From, newRelation)); } // Excludes to old must exists beforehand if (Activities.Any(x => x.Id.Equals(newRelation.To.Id)) && !_relations.Any(x => x.Type == Relation.RelationType.Exclude && x.From.Id.Equals(newRelation.From.Id) && x.To.Id.Equals(newRelation.To.Id))) { return(new Tuple <Activity, Relation>(newRelation.From, newRelation)); } break; case Relation.RelationType.Response: // not between old if (Activities.Any(x => x.Id.Equals(newRelation.From.Id)) && Activities.Any(x => x.Id.Equals(newRelation.To.Id))) { return(new Tuple <Activity, Relation>(newRelation.From, newRelation)); } //no old to new //if (Activities.Any(x => x.Id.Equals(newRelation.From.Id)) && !Activities.Any(x => x.Id.Equals(newRelation.To.Id))) return new Tuple<Activity, Relation>(newRelation.From, newRelation); break; case Relation.RelationType.Condition: case Relation.RelationType.Milestone: //must not add from old activities if (Activities.Any(x => x.Id.Equals(newRelation.From.Id))) { return(new Tuple <Activity, Relation>(newRelation.From, newRelation)); } // Can only add from new if new is safe if (Activities.Any(x => x.Id.Equals(newRelation.To.Id) && !mergedGraph.Activities.First(y => y.Id.Equals(newRelation.From.Id)).IsSafe(mergedGraph))) { return(new Tuple <Activity, Relation>(newRelation.From, newRelation)); } break; } } return(new Tuple <Activity, Relation>(null, null)); }
private void CreateRelatedGraph() { // find all directly shared activities var sharedActivities = new List <Activity>(); foreach (var dcrGraph in DcrGraphs) { foreach (var activity in dcrGraph.Activities) { if (sharedActivities.Any(x => x.Id.Equals(activity.Id))) { continue; } foreach (var x in DcrGraphs) { var q = !x.Name.Equals(dcrGraph.Name); var w = x.Activities.Any(y => y.Id.Equals(activity.Id)); if (q && w) { sharedActivities.Add(activity); break; } } } } //Build the fully merged graph var mergeDcrString = ""; foreach (var dcrGraph in DcrGraphs) { mergeDcrString += " \r\n " + dcrGraph.EditWindowString; } var mergedGraph = new DcrGraph(mergeDcrString, new List <string>(), mergeDcrString, "relatedGraph"); // get the shared activities now that they have the merged relations var sharedActivitiesWithProperRelations = new List <Activity>(); foreach (var sharedActivity in sharedActivities) { sharedActivitiesWithProperRelations.Add(mergedGraph.Activities.First(x => x.Id.Equals(sharedActivity.Id))); } // Add in the dependency graph for (var i = 0; i < sharedActivitiesWithProperRelations.Count; i++) { var activity = sharedActivitiesWithProperRelations[i]; var dependencyGraph = activity.BuildDependencyGraph(); foreach (var activity1 in dependencyGraph) { if (sharedActivitiesWithProperRelations.Any(x => x.Id.Equals(activity1.Id))) { continue; } sharedActivitiesWithProperRelations.Add(activity1); } } // remove irrelevant activities/relations foreach (var activity in sharedActivitiesWithProperRelations) { var toBeRemovedIn = new List <Relation>(); foreach (var relation in activity._relationsIncoming) { if (sharedActivitiesWithProperRelations.Any(x => !x.Id.Equals(relation.From.Id))) { toBeRemovedIn.Add(relation); } } var toBeRemovedOut = new List <Relation>(); foreach (var relation in activity._relationsOutgoing) { if (sharedActivitiesWithProperRelations.Any(x => !x.Id.Equals(relation.To.Id))) { toBeRemovedOut.Add(relation); } } foreach (var relation in toBeRemovedIn) { if (!relation.To._relationsIncoming.Remove(relation)) { Console.WriteLine(relation.ToString() + " could not be removed in Freedom.cs"); } } foreach (var relation in toBeRemovedOut) { if (!relation.From._relationsOutgoing.Remove(relation)) { Console.WriteLine(relation.ToString() + " could not be removed in Freedom.cs"); } } } for (var i = 0; i < mergedGraph.Activities.Count; i++) { var activity = mergedGraph.Activities[i]; if (sharedActivitiesWithProperRelations.Any(x => x.Id.Equals(activity.Id))) { continue; } mergedGraph.Activities.Remove(activity); i--; } var rawDcr = mergedGraph.ExportRawDcrString(); RelatedDcrGraph = new DcrGraph(rawDcr, new List <string>(), rawDcr, "RelatedGraph"); }
private void FindLivelocks() { var cycleChecker = new CycleChecker(); foreach (var dcrGraph in DcrGraphs) { var deadCycles = cycleChecker.GetAllCycleConditionMilestone(dcrGraph.Activities); var liveCycles = cycleChecker.GetAllCycleResponse(dcrGraph.Activities); if (liveCycles == null && deadCycles == null) { return; } var noDead = new List <bool>(); if (deadCycles != null) { foreach (var deadCycle in deadCycles) { if (deadCycle.All(x => !x.Pending && x._relationsIncoming.All(y => y.Type != Relation.RelationType.Response))) { if (deadCycle.Any(x => x._relationsOutgoing.Any(y => (y.Type == Relation.RelationType.Condition || y.Type == Relation.RelationType.Milestone) && !y.To.Id.Equals(y.From.Id)))) { noDead.Add(false); continue; } noDead.Add(true); continue; } var possiblyPending = deadCycle.Where(x => x.Pending || x._relationsIncoming.Any(y => y.Type == Relation.RelationType.Response)).ToList(); if (possiblyPending.Any()) { foreach (var activity in possiblyPending) { var graphWithNoExcludeToActivityBeingTested = new DcrGraph(dcrGraph.EditWindowString, new List <string>(), dcrGraph.EditWindowString, "graphWithNoRelationsToActivityBeingTested"); var perhapsSafeActivity = graphWithNoExcludeToActivityBeingTested.Activities.Where(x => x._relationsOutgoing.Any(y => y.To.Id.Equals(activity.Id) && y.Type == Relation.RelationType.Exclude)).ToList(); foreach (var activity1 in perhapsSafeActivity) { activity1._relationsOutgoing.Remove(activity1._relationsOutgoing.First(x => x.Type == Relation.RelationType.Exclude && x.To.Id.Equals(activity.Id))); } var anySafeExlude = perhapsSafeActivity.Any(x => x.IsSafe(graphWithNoExcludeToActivityBeingTested) && x._relationsIncoming.All(y => y.Type != Relation.RelationType.Exclude)); if (!(activity.Excluded || anySafeExlude)) { noDead.Add(false); break; } else { noDead.Add(true); } } //noDead.Add(true); } else { noDead.Add(true); } } for (int i = 0; i < deadCycles.Count; i++) { var cycle = deadCycles[i]; bool live = noDead[i]; if (!live) { Livelokcs.Add(new Tuple <DcrGraph, List <Activity> >(dcrGraph, cycle)); } } } var noLive = new List <bool>(); if (liveCycles != null) { foreach (var liveCycle in liveCycles) { // all safe if (liveCycle.All(x => x.IsSafe(dcrGraph))) { noLive.Add(true); continue; } // exist always excluded never included in circle if (liveCycle.Any(x => (x.Excluded && x._relationsIncoming.All(y => y.Type == Relation.RelationType.Include)) || x._relationsIncoming.Any(y => y.Type == Relation.RelationType.Exclude && y.From.IsSafe(CreateXE(dcrGraph, y.From)) && y.From._relationsIncoming.All(z => z.Type != Relation.RelationType.Exclude)) && x._relationsIncoming.All(c => c.Type != Relation.RelationType.Include))) { noLive.Add(true); continue; } noLive.Add(false); } for (int i = 0; i < liveCycles.Count; i++) { var cycle = liveCycles[i]; bool live = noLive[i]; if (!live) { Livelokcs.Add(new Tuple <DcrGraph, List <Activity> >(dcrGraph, cycle)); } } } } }