How to use Merge method of Microsoft.Coyote.Actors.Coverage.ActorRuntimeLogGraphBuilder class

Best Coyote code snippet using Microsoft.Coyote.Actors.Coverage.ActorRuntimeLogGraphBuilder.Merge

ActorRuntimeLogGraphBuilder.cs

Source:ActorRuntimeLogGraphBuilder.cs Github

copy

Full Screen

...18 {19 private Graph CurrentGraph;20 private readonly Dictionary<ActorId, EventInfo> Dequeued = new Dictionary<ActorId, EventInfo>(); // current dequeued event.21 private readonly Dictionary<ActorId, string> HaltedStates = new Dictionary<ActorId, string>(); // halted state for given actor.22 private readonly bool MergeEventLinks; // merge events from node A to node B instead of making them separate links.23 private const string ExternalCodeName = "ExternalCode";24 private const string ExternalStateName = "ExternalState";25 private const string StateMachineCategory = "StateMachine";26 private const string ActorCategory = "Actor";27 private const string MonitorCategory = "Monitor";28 private class EventInfo29 {30 public string Name;31 public string Type;32 public string State;33 public string Event;34 public string HandlingState;35 }36 private readonly Dictionary<string, List<EventInfo>> Inbox = new Dictionary<string, List<EventInfo>>();37 private static readonly Dictionary<string, string> EventAliases = new Dictionary<string, string>();38 private readonly HashSet<string> Namespaces = new HashSet<string>();39 private static readonly char[] TypeSeparators = new char[] { '.', '+' };40 private class DoActionEvent : Event41 {42 }43 private class PopStateEvent : Event44 {45 }46 static ActorRuntimeLogGraphBuilder()47 {48 EventAliases[typeof(GotoStateEvent).FullName] = "goto";49 EventAliases[typeof(HaltEvent).FullName] = "halt";50 EventAliases[typeof(DefaultEvent).FullName] = "default";51 EventAliases[typeof(PushStateEvent).FullName] = "push";52 EventAliases[typeof(QuiescentEvent).FullName] = "quiescent";53 EventAliases[typeof(WildCardEvent).FullName] = "*";54 EventAliases[typeof(TimerElapsedEvent).FullName] = "timer_elapsed";55 EventAliases[typeof(TimerSetupEvent).FullName] = "timer_setup";56 EventAliases[typeof(DoActionEvent).FullName] = "do";57 EventAliases[typeof(PopStateEvent).FullName] = "pop";58 }59 /// <summary>60 /// Initializes a new instance of the <see cref="ActorRuntimeLogGraphBuilder"/> class.61 /// </summary>62 public ActorRuntimeLogGraphBuilder(bool mergeEventLinks)63 {64 this.MergeEventLinks = mergeEventLinks;65 this.CurrentGraph = new Graph();66 }67 /// <summary>68 /// Set this boolean to true to get a collapsed graph showing only69 /// machine types, states and events. This will not show machine "instances".70 /// </summary>71 public bool CollapseMachineInstances { get; set; }72 /// <summary>73 /// Get or set the underlying logging object.74 /// </summary>75 /// <remarks>76 /// See <see href="/coyote/advanced-topics/actors/logging" >Logging</see> for more information.77 /// </remarks>78 public TextWriter Logger { get; set; }79 /// <summary>80 /// Get the Graph object built by this logger.81 /// </summary>82 public Graph Graph83 {84 get85 {86 if (this.CurrentGraph is null)87 {88 this.CurrentGraph = new Graph();89 }90 return this.CurrentGraph;91 }92 }93 /// <inheritdoc/>94 public void OnCreateActor(ActorId id, string creatorName, string creatorType)95 {96 lock (this.Inbox)97 {98 var resolvedId = this.GetResolveActorId(id?.Name, id?.Type);99 GraphNode node = this.Graph.GetOrCreateNode(resolvedId);100 node.Category = ActorCategory;101 if (!string.IsNullOrEmpty(creatorName))102 {103 var creatorId = this.GetResolveActorId(creatorName, creatorType);104 GraphNode creator = this.Graph.GetOrCreateNode(creatorId);105 this.GetOrCreateEventLink(creator, node, new EventInfo() { Event = "CreateActor" });106 }107 }108 }109 /// <inheritdoc/>110 public void OnCreateStateMachine(ActorId id, string creatorName, string creatorType)111 {112 lock (this.Inbox)113 {114 var resolvedId = this.GetResolveActorId(id?.Name, id?.Type);115 GraphNode node = this.Graph.GetOrCreateNode(resolvedId);116 node.Category = StateMachineCategory;117 if (!string.IsNullOrEmpty(creatorName))118 {119 var creatorId = this.GetResolveActorId(creatorName, creatorType);120 GraphNode creator = this.Graph.GetOrCreateNode(creatorId);121 this.GetOrCreateEventLink(creator, node, new EventInfo() { Event = "CreateActor" });122 }123 }124 }125 /// <inheritdoc/>126 public void OnSendEvent(ActorId targetActorId, string senderName, string senderType, string senderStateName,127 Event e, Guid eventGroupId, bool isTargetHalted)128 {129 string eventName = e.GetType().FullName;130 this.AddEvent(targetActorId.Name, targetActorId.Type, senderName, senderType, senderStateName, eventName);131 }132 /// <inheritdoc/>133 public void OnRaiseEvent(ActorId id, string stateName, Event e)134 {135 string eventName = e.GetType().FullName;136 // Raising event to self.137 this.AddEvent(id.Name, id.Type, id.Name, id.Type, stateName, eventName);138 }139 /// <inheritdoc/>140 public void OnEnqueueEvent(ActorId id, Event e)141 {142 }143 /// <inheritdoc/>144 public void OnDequeueEvent(ActorId id, string stateName, Event e)145 {146 lock (this.Inbox)147 {148 var resolvedId = this.GetResolveActorId(id?.Name, id?.Type);149 string eventName = e.GetType().FullName;150 EventInfo info = this.PopEvent(resolvedId, eventName);151 if (info != null)152 {153 this.Dequeued[id] = info;154 }155 }156 }157 private EventInfo PopEvent(string resolvedId, string eventName)158 {159 EventInfo result = null;160 lock (this.Inbox)161 {162 if (this.Inbox.TryGetValue(resolvedId, out List<EventInfo> inbox))163 {164 for (int i = inbox.Count - 1; i >= 0; i--)165 {166 if (inbox[i].Event == eventName)167 {168 result = inbox[i];169 inbox.RemoveAt(i);170 }171 }172 }173 }174 return result;175 }176 /// <inheritdoc/>177 public void OnReceiveEvent(ActorId id, string stateName, Event e, bool wasBlocked)178 {179 string resolvedId = this.GetResolveActorId(id?.Name, id?.Type);180 lock (this.Inbox)181 {182 if (this.Inbox.TryGetValue(resolvedId, out List<EventInfo> inbox))183 {184 string eventName = e.GetType().FullName;185 for (int i = inbox.Count - 1; i >= 0; i--)186 {187 EventInfo info = inbox[i];188 if (info.Event == eventName)189 {190 // Yay, found it so we can draw the complete link connecting the Sender state to this state!191 string category = string.IsNullOrEmpty(stateName) ? ActorCategory : StateMachineCategory;192 var source = this.GetOrCreateChild(info.Name, info.Type, info.State);193 var target = this.GetOrCreateChild(id?.Name, id?.Type, category, stateName);194 this.GetOrCreateEventLink(source, target, info);195 inbox.RemoveAt(i);196 break;197 }198 }199 }200 }201 }202 /// <inheritdoc/>203 public void OnWaitEvent(ActorId id, string stateName, Type eventType)204 {205 }206 /// <inheritdoc/>207 public void OnWaitEvent(ActorId id, string stateName, params Type[] eventTypes)208 {209 }210 /// <inheritdoc/>211 public void OnStateTransition(ActorId id, string stateName, bool isEntry)212 {213 if (isEntry)214 {215 // record the fact we have entered this state216 this.GetOrCreateChild(id?.Name, id?.Type, stateName);217 }218 }219 /// <inheritdoc/>220 public void OnExecuteAction(ActorId id, string handlingStateName, string currentStateName, string actionName)221 {222 this.LinkTransition(typeof(DoActionEvent), id, handlingStateName, currentStateName, null);223 }224 /// <inheritdoc/>225 public void OnGotoState(ActorId id, string currentStateName, string newStateName)226 {227 this.LinkTransition(typeof(GotoStateEvent), id, currentStateName, currentStateName, newStateName);228 }229 /// <inheritdoc/>230 public void OnPushState(ActorId id, string currentStateName, string newStateName)231 {232 this.LinkTransition(typeof(PushStateEvent), id, currentStateName, currentStateName, newStateName);233 }234 /// <inheritdoc/>235 public void OnPopState(ActorId id, string currentStateName, string restoredStateName)236 {237 if (!string.IsNullOrEmpty(currentStateName))238 {239 this.LinkTransition(typeof(PopStateEvent), id, currentStateName,240 currentStateName, restoredStateName);241 }242 }243 /// <inheritdoc/>244 public void OnHalt(ActorId id, int inboxSize)245 {246 lock (this.Inbox)247 {248 this.HaltedStates.TryGetValue(id, out string stateName);249 var target = this.GetOrCreateChild(id?.Name, id?.Type, "Halt", "Halt");250 // Transition to the Halt state.251 if (!string.IsNullOrEmpty(stateName))252 {253 var source = this.GetOrCreateChild(id?.Name, id?.Type, stateName);254 this.GetOrCreateEventLink(source, target, new EventInfo() { Event = typeof(HaltEvent).FullName });255 }256 }257 }258 private int? GetLinkIndex(GraphNode source, GraphNode target, string id)259 {260 if (this.MergeEventLinks)261 {262 return null;263 }264 return this.Graph.GetUniqueLinkIndex(source, target, id);265 }266 /// <inheritdoc/>267 public void OnDefaultEventHandler(ActorId id, string stateName)268 {269 lock (this.Inbox)270 {271 string resolvedId = this.GetResolveActorId(id?.Name, id?.Type);272 string eventName = typeof(DefaultEvent).FullName;273 this.AddEvent(id.Name, id.Type, id.Name, id.Type, stateName, eventName);274 this.Dequeued[id] = this.PopEvent(resolvedId, eventName);275 }276 }277 /// <inheritdoc/>278 public void OnHandleRaisedEvent(ActorId id, string stateName, Event e)279 {280 lock (this.Inbox)281 {282 // We used the inbox to store raised event, but it should be the first one handled since283 // raised events are highest priority.284 string resolvedId = this.GetResolveActorId(id?.Name, id?.Type);285 lock (this.Inbox)286 {287 if (this.Inbox.TryGetValue(resolvedId, out List<EventInfo> inbox))288 {289 string eventName = e.GetType().FullName;290 for (int i = inbox.Count - 1; i >= 0; i--)291 {292 EventInfo info = inbox[i];293 if (info.Event == eventName)294 {295 this.Dequeued[id] = info;296 break;297 }298 }299 }300 }301 }302 }303 /// <inheritdoc/>304 public void OnPopStateUnhandledEvent(ActorId actorId, string currentStateName, Event e)305 {306 lock (this.Inbox)307 {308 if (e is HaltEvent)309 {310 this.HaltedStates[actorId] = currentStateName;311 }312 }313 }314 /// <inheritdoc/>315 public void OnExceptionThrown(ActorId id, string stateName, string actionName, Exception ex)316 {317 }318 /// <inheritdoc/>319 public void OnExceptionHandled(ActorId id, string stateName, string actionName, Exception ex)320 {321 }322 /// <inheritdoc/>323 public void OnCreateTimer(TimerInfo info)324 {325 // TODO: figure out how to graph timers when we have no "timer id" at this point...326 }327 /// <inheritdoc/>328 public void OnStopTimer(TimerInfo info)329 {330 }331 /// <inheritdoc/>332 public void OnCreateMonitor(string monitorType)333 {334 lock (this.Inbox)335 {336 GraphNode node = this.Graph.GetOrCreateNode(monitorType, monitorType);337 node.Category = MonitorCategory;338 }339 }340 /// <inheritdoc/>341 public void OnMonitorExecuteAction(string monitorType, string stateName, string actionName)342 {343 // Monitors process actions immediately, so this state transition is a result of the only event in the inbox.344 lock (this.Inbox)345 {346 if (this.Inbox.TryGetValue(monitorType, out List<EventInfo> inbox) && inbox.Count > 0)347 {348 var e = inbox[inbox.Count - 1];349 inbox.RemoveAt(inbox.Count - 1);350 // Draw the link connecting the Sender state to this state!351 var source = this.GetOrCreateChild(e.Name, e.Type, e.State);352 var target = this.GetOrCreateChild(monitorType, monitorType, stateName);353 this.GetOrCreateEventLink(source, target, e);354 }355 }356 }357 /// <inheritdoc/>358 public void OnMonitorProcessEvent(string monitorType, string stateName, string senderName, string senderType,359 string senderStateName, Event e)360 {361 lock (this.Inbox)362 {363 string eventName = e.GetType().FullName;364 // Now add a fake event for internal monitor state transition that might now happen as a result of this event,365 // storing the monitor's current state in this event.366 var info = this.AddEvent(monitorType, monitorType, monitorType, monitorType, stateName, eventName);367 // Draw the link connecting the Sender state to this state!368 var source = this.GetOrCreateChild(senderName, senderType, senderStateName);369 var target = this.GetOrCreateChild(monitorType, monitorType, stateName);370 this.GetOrCreateEventLink(source, target, info);371 }372 }373 /// <inheritdoc/>374 public void OnMonitorRaiseEvent(string monitorType, string stateName, Event e)375 {376 // Raising event to self.377 string eventName = e.GetType().FullName;378 this.AddEvent(monitorType, monitorType, monitorType, monitorType, stateName, eventName);379 }380 /// <inheritdoc/>381 public void OnMonitorStateTransition(string monitorType, string stateName, bool isEntry, bool? isInHotState)382 {383 if (isEntry)384 {385 lock (this.Inbox)386 {387 // Monitors process events immediately (and does not call OnDequeue), so this state transition is a result of388 // the fake event we created in OnMonitorProcessEvent.389 if (this.Inbox.TryGetValue(monitorType, out List<EventInfo> inbox) && inbox.Count > 0)390 {391 var info = inbox[inbox.Count - 1];392 inbox.RemoveAt(inbox.Count - 1);393 // draw the link connecting the current state to this new state!394 var source = this.GetOrCreateChild(monitorType, monitorType, info.State);395 var shortStateName = this.GetLabel(monitorType, monitorType, stateName);396 string suffix = string.Empty;397 if (isInHotState.HasValue)398 {399 suffix = (isInHotState is true) ? "[hot]" : "[cold]";400 shortStateName += suffix;401 }402 string label = shortStateName;403 var target = this.GetOrCreateChild(monitorType, monitorType, shortStateName, label);404 // In case this node was already created, we may need to override the label here now that405 // we know this is a hot state. This is because, unfortunately, other OnMonitor* methods406 // do not provide the isInHotState parameter.407 target.Label = label;408 this.GetOrCreateEventLink(source, target, info);409 }410 }411 }412 }413 /// <inheritdoc/>414 public void OnMonitorError(string monitorType, string stateName, bool? isInHotState)415 {416 var source = this.GetOrCreateChild(monitorType, monitorType, stateName);417 source.Category = "Error";418 }419 /// <inheritdoc/>420 public void OnRandom(object result, string callerName, string callerType)421 {422 }423 /// <inheritdoc/>424 public void OnAssertionFailure(string error)425 {426 }427 /// <inheritdoc/>428 public void OnStrategyDescription(string strategyName, string description)429 {430 }431 /// <inheritdoc/>432 public void OnCompleted()433 {434 }435 /// <summary>436 /// Return current graph and reset for next iteration.437 /// </summary>438 /// <param name="reset">Set to true will reset the graph for the next iteration.</param>439 /// <returns>The graph.</returns>440 public Graph SnapshotGraph(bool reset)441 {442 Graph result = this.CurrentGraph;443 if (reset)444 {445 // start fresh.446 this.CurrentGraph = null;447 }448 return result;449 }450 private string GetResolveActorId(string name, string type)451 {452 if (type is null)453 {454 // The sender id can be null if an event is fired from non-actor code.455 return ExternalCodeName;456 }457 if (this.CollapseMachineInstances)458 {459 return type;460 }461 return name;462 }463 private EventInfo AddEvent(string targetName, string targetType, string senderName, string senderType,464 string senderStateName, string eventName)465 {466 string targetId = this.GetResolveActorId(targetName, targetType);467 EventInfo info = null;468 lock (this.Inbox)469 {470 if (!this.Inbox.TryGetValue(targetId, out List<EventInfo> inbox))471 {472 inbox = new List<EventInfo>();473 this.Inbox[targetId] = inbox;474 }475 info = new EventInfo()476 {477 Name = senderName ?? ExternalCodeName,478 Type = senderType ?? ExternalCodeName,479 State = senderStateName,480 Event = eventName481 };482 inbox.Add(info);483 }484 return info;485 }486 private void LinkTransition(Type transitionType, ActorId id, string handlingStateName,487 string currentStateName, string newStateName)488 {489 string name = id.Name;490 string type = id.Type;491 lock (this.Inbox)492 {493 if (this.Dequeued.TryGetValue(id, out EventInfo info))494 {495 // Event was dequeued, but now we know what state is handling this event, so connect the dots...496 if (info.Type != type || info.Name != name || info.State != currentStateName)497 {498 var source = this.GetOrCreateChild(info.Name, info.Type, info.State);499 var target = this.GetOrCreateChild(name, type, currentStateName);500 info.HandlingState = handlingStateName;501 this.GetOrCreateEventLink(source, target, info);502 }503 }504 if (newStateName != null)505 {506 // Then this is a goto or push and we can draw that link also.507 var source = this.GetOrCreateChild(name, type, currentStateName);508 var target = this.GetOrCreateChild(name, type, newStateName);509 if (info is null)510 {511 info = new EventInfo { Event = transitionType.FullName };512 }513 this.GetOrCreateEventLink(source, target, info);514 }515 this.Dequeued.Remove(id);516 }517 }518 private GraphNode GetOrCreateChild(string name, string type, string stateName, string label = null)519 {520 GraphNode child = null;521 lock (this.Inbox)522 {523 this.AddNamespace(type);524 var initalStateName = stateName;525 // make label relative to fully qualified actor id (it's usually a nested class).526 stateName = this.GetLabel(name, type, stateName);527 string id = this.GetResolveActorId(name, type);528 GraphNode parent = this.Graph.GetOrCreateNode(id);529 parent.AddAttribute("Group", "Expanded");530 if (string.IsNullOrEmpty(label))531 {532 label = stateName ?? ExternalStateName;533 }534 if (!string.IsNullOrEmpty(stateName))535 {536 id += "." + stateName;537 }538 child = this.Graph.GetOrCreateNode(id, label);539 this.Graph.GetOrCreateLink(parent, child, null, null, "Contains");540 }541 return child;542 }543 private GraphLink GetOrCreateEventLink(GraphNode source, GraphNode target, EventInfo e)544 {545 GraphLink link = null;546 lock (this.Inbox)547 {548 string label = this.GetEventLabel(e.Event);549 var index = this.GetLinkIndex(source, target, label);550 var category = GetEventCategory(e.Event);551 link = this.Graph.GetOrCreateLink(source, target, index, label, category);552 if (this.MergeEventLinks)553 {554 if (link.AddListAttribute("EventIds", e.Event) > 1)555 {556 link.Label = "*";557 }558 }559 else560 {561 if (e.Event != null)562 {563 link.AddAttribute("EventId", e.Event);564 }565 if (e.HandlingState != null)566 {567 link.AddAttribute("HandledBy", e.HandlingState);568 }569 }570 }571 return link;572 }573 private void AddNamespace(string type)574 {575 if (type != null && !this.Namespaces.Contains(type))576 {577 string typeName = type;578 int index = typeName.Length;579 do580 {581 typeName = typeName.Substring(0, index);582 this.Namespaces.Add(typeName);583 index = typeName.LastIndexOfAny(TypeSeparators);584 }585 while (index > 0);586 }587 }588 private string GetLabel(string name, string type, string fullyQualifiedName)589 {590 if (type is null)591 {592 // external code593 return fullyQualifiedName;594 }595 this.AddNamespace(type);596 if (string.IsNullOrEmpty(fullyQualifiedName))597 {598 // then this is probably an Actor, not a StateMachine. For Actors we can invent a state599 // name equal to the short name of the class, this then looks like a Constructor which is fine.600 fullyQualifiedName = this.CollapseMachineInstances ? type : name;601 }602 var len = fullyQualifiedName.Length;603 var index = fullyQualifiedName.LastIndexOfAny(TypeSeparators);604 if (index > 0)605 {606 fullyQualifiedName = fullyQualifiedName.Substring(index).Trim('+').Trim('.');607 }608 return fullyQualifiedName;609 }610 private string GetEventLabel(string fullyQualifiedName)611 {612 if (EventAliases.TryGetValue(fullyQualifiedName, out string label))613 {614 return label;615 }616 int i = fullyQualifiedName.LastIndexOfAny(TypeSeparators);617 if (i > 0)618 {619 string ns = fullyQualifiedName.Substring(0, i);620 if (this.Namespaces.Contains(ns))621 {622 return fullyQualifiedName.Substring(i + 1);623 }624 }625 return fullyQualifiedName;626 }627 private static string GetEventCategory(string fullyQualifiedName)628 {629 if (EventAliases.TryGetValue(fullyQualifiedName, out string label))630 {631 return label;632 }633 return null;634 }635 }636 /// <summary>637 /// A directed graph made up of Nodes and Links.638 /// </summary>639 [DataContract]640 public class Graph641 {642 internal const string DgmlNamespace = "http://schemas.microsoft.com/vs/2009/dgml";643 // These [DataMember] fields are here so we can serialize the Graph across parallel or distributed644 // test processes without losing any information. There is more information here than in the serialized645 // DGML which is we we can't just use Save/LoadDgml to do the same.646 [DataMember]647 private readonly Dictionary<string, GraphNode> InternalNodes = new Dictionary<string, GraphNode>();648 [DataMember]649 private readonly Dictionary<string, GraphLink> InternalLinks = new Dictionary<string, GraphLink>();650 // last used index for simple link key "a->b".651 [DataMember]652 private readonly Dictionary<string, int> InternalNextLinkIndex = new Dictionary<string, int>();653 // maps augmented link key to the index that has been allocated for that link id "a->b(goto)" => 0654 [DataMember]655 private readonly Dictionary<string, int> InternalAllocatedLinkIndexes = new Dictionary<string, int>();656 [DataMember]657 private readonly Dictionary<string, string> InternalAllocatedLinkIds = new Dictionary<string, string>();658 /// <summary>659 /// Return the current list of nodes (in no particular order).660 /// </summary>661 public IEnumerable<GraphNode> Nodes662 {663 get { return this.InternalNodes.Values; }664 }665 /// <summary>666 /// Return the current list of links (in no particular order).667 /// </summary>668 public IEnumerable<GraphLink> Links669 {670 get671 {672 if (this.InternalLinks is null)673 {674 return Array.Empty<GraphLink>();675 }676 return this.InternalLinks.Values;677 }678 }679 /// <summary>680 /// Get existing node or null.681 /// </summary>682 /// <param name="id">The id of the node.</param>683 public GraphNode GetNode(string id)684 {685 this.InternalNodes.TryGetValue(id, out GraphNode node);686 return node;687 }688 /// <summary>689 /// Get existing node or create a new one with the given id and label.690 /// </summary>691 /// <returns>Returns the new node or the existing node if it was already defined.</returns>692 public GraphNode GetOrCreateNode(string id, string label = null, string category = null)693 {694 if (!this.InternalNodes.TryGetValue(id, out GraphNode node))695 {696 node = new GraphNode(id, label, category);697 this.InternalNodes.Add(id, node);698 }699 return node;700 }701 /// <summary>702 /// Get existing node or create a new one with the given id and label.703 /// </summary>704 /// <returns>Returns the new node or the existing node if it was already defined.</returns>705 private GraphNode GetOrCreateNode(GraphNode newNode)706 {707 if (!this.InternalNodes.ContainsKey(newNode.Id))708 {709 this.InternalNodes.Add(newNode.Id, newNode);710 }711 return newNode;712 }713 /// <summary>714 /// Get existing link or create a new one connecting the given source and target nodes.715 /// </summary>716 /// <returns>The new link or the existing link if it was already defined.</returns>717 public GraphLink GetOrCreateLink(GraphNode source, GraphNode target, int? index = null, string linkLabel = null, string category = null)718 {719 string key = source.Id + "->" + target.Id;720 if (index.HasValue)721 {722 key += string.Format("({0})", index.Value);723 }724 if (!this.InternalLinks.TryGetValue(key, out GraphLink link))725 {726 link = new GraphLink(source, target, linkLabel, category);727 if (index.HasValue)728 {729 link.Index = index.Value;730 }731 this.InternalLinks.Add(key, link);732 }733 return link;734 }735 internal int GetUniqueLinkIndex(GraphNode source, GraphNode target, string id)736 {737 // augmented key738 string key = string.Format("{0}->{1}({2})", source.Id, target.Id, id);739 if (this.InternalAllocatedLinkIndexes.TryGetValue(key, out int index))740 {741 return index;742 }743 // allocate a new index for the simple key744 var simpleKey = string.Format("{0}->{1}", source.Id, target.Id);745 if (this.InternalNextLinkIndex.TryGetValue(simpleKey, out index))746 {747 index++;748 }749 this.InternalNextLinkIndex[simpleKey] = index;750 // remember this index has been allocated for this link id.751 this.InternalAllocatedLinkIndexes[key] = index;752 // remember the original id associated with this link index.753 key = string.Format("{0}->{1}({2})", source.Id, target.Id, index);754 this.InternalAllocatedLinkIds[key] = id;755 return index;756 }757 /// <summary>758 /// Serialize the graph to a DGML string.759 /// </summary>760 public override string ToString()761 {762 using (var writer = new StringWriter())763 {764 this.WriteDgml(writer, false);765 return writer.ToString();766 }767 }768 internal void SaveDgml(string graphFilePath, bool includeDefaultStyles)769 {770 using (StreamWriter writer = new StreamWriter(graphFilePath, false, Encoding.UTF8))771 {772 this.WriteDgml(writer, includeDefaultStyles);773 }774 }775 /// <summary>776 /// Serialize the graph to DGML.777 /// </summary>778 public void WriteDgml(TextWriter writer, bool includeDefaultStyles)779 {780 writer.WriteLine("<DirectedGraph xmlns='{0}'>", DgmlNamespace);781 writer.WriteLine(" <Nodes>");782 if (this.InternalNodes != null)783 {784 List<string> nodes = new List<string>(this.InternalNodes.Keys);785 nodes.Sort(StringComparer.Ordinal);786 foreach (var id in nodes)787 {788 GraphNode node = this.InternalNodes[id];789 writer.Write(" <Node Id='{0}'", node.Id);790 if (!string.IsNullOrEmpty(node.Label))791 {792 writer.Write(" Label='{0}'", node.Label);793 }794 if (!string.IsNullOrEmpty(node.Category))795 {796 writer.Write(" Category='{0}'", node.Category);797 }798 node.WriteAttributes(writer);799 writer.WriteLine("/>");800 }801 }802 writer.WriteLine(" </Nodes>");803 writer.WriteLine(" <Links>");804 if (this.InternalLinks != null)805 {806 List<string> links = new List<string>(this.InternalLinks.Keys);807 links.Sort(StringComparer.Ordinal);808 foreach (var id in links)809 {810 GraphLink link = this.InternalLinks[id];811 writer.Write(" <Link Source='{0}' Target='{1}'", link.Source.Id, link.Target.Id);812 if (!string.IsNullOrEmpty(link.Label))813 {814 writer.Write(" Label='{0}'", link.Label);815 }816 if (!string.IsNullOrEmpty(link.Category))817 {818 writer.Write(" Category='{0}'", link.Category);819 }820 if (link.Index.HasValue)821 {822 writer.Write(" Index='{0}'", link.Index.Value);823 }824 link.WriteAttributes(writer);825 writer.WriteLine("/>");826 }827 }828 writer.WriteLine(" </Links>");829 if (includeDefaultStyles)830 {831 writer.WriteLine(832@" <Styles>833 <Style TargetType=""Node"" GroupLabel=""Error"" ValueLabel=""True"">834 <Condition Expression=""HasCategory('Error')"" />835 <Setter Property=""Background"" Value=""#FFC15656"" />836 </Style>837 <Style TargetType=""Node"" GroupLabel=""Actor"" ValueLabel=""True"">838 <Condition Expression=""HasCategory('Actor')"" />839 <Setter Property=""Background"" Value=""#FF57AC56"" />840 </Style>841 <Style TargetType=""Node"" GroupLabel=""Monitor"" ValueLabel=""True"">842 <Condition Expression=""HasCategory('Monitor')"" />843 <Setter Property=""Background"" Value=""#FF558FDA"" />844 </Style>845 <Style TargetType=""Link"" GroupLabel=""halt"" ValueLabel=""True"">846 <Condition Expression=""HasCategory('halt')"" />847 <Setter Property=""Stroke"" Value=""#FFFF6C6C"" />848 <Setter Property=""StrokeDashArray"" Value=""4 2"" />849 </Style>850 <Style TargetType=""Link"" GroupLabel=""push"" ValueLabel=""True"">851 <Condition Expression=""HasCategory('push')"" />852 <Setter Property=""Stroke"" Value=""#FF7380F5"" />853 <Setter Property=""StrokeDashArray"" Value=""4 2"" />854 </Style>855 <Style TargetType=""Link"" GroupLabel=""pop"" ValueLabel=""True"">856 <Condition Expression=""HasCategory('pop')"" />857 <Setter Property=""Stroke"" Value=""#FF7380F5"" />858 <Setter Property=""StrokeDashArray"" Value=""4 2"" />859 </Style>860 </Styles>");861 }862 writer.WriteLine("</DirectedGraph>");863 }864 /// <summary>865 /// Load a DGML file into a new Graph object.866 /// </summary>867 /// <param name="graphFilePath">Full path to the DGML file.</param>868 /// <returns>The loaded Graph object.</returns>869 public static Graph LoadDgml(string graphFilePath)870 {871 XDocument doc = XDocument.Load(graphFilePath);872 Graph result = new Graph();873 var ns = doc.Root.Name.Namespace;874 if (ns != DgmlNamespace)875 {876 throw new Exception(string.Format("File '{0}' does not contain the DGML namespace", graphFilePath));877 }878 foreach (var e in doc.Root.Element(ns + "Nodes").Elements(ns + "Node"))879 {880 var id = (string)e.Attribute("Id");881 var label = (string)e.Attribute("Label");882 var category = (string)e.Attribute("Category");883 GraphNode node = new GraphNode(id, label, category);884 node.AddDgmlProperties(e);885 result.GetOrCreateNode(node);886 }887 foreach (var e in doc.Root.Element(ns + "Links").Elements(ns + "Link"))888 {889 var srcId = (string)e.Attribute("Source");890 var targetId = (string)e.Attribute("Target");891 var label = (string)e.Attribute("Label");892 var category = (string)e.Attribute("Category");893 var srcNode = result.GetOrCreateNode(srcId);894 var targetNode = result.GetOrCreateNode(targetId);895 XAttribute indexAttr = e.Attribute("index");896 int? index = null;897 if (indexAttr != null)898 {899 index = (int)indexAttr;900 }901 var link = result.GetOrCreateLink(srcNode, targetNode, index, label, category);902 link.AddDgmlProperties(e);903 }904 return result;905 }906 /// <summary>907 /// Merge the given graph so that this graph becomes a superset of both graphs.908 /// </summary>909 /// <param name="other">The new graph to merge into this graph.</param>910 public void Merge(Graph other)911 {912 foreach (var node in other.InternalNodes.Values)913 {914 var newNode = this.GetOrCreateNode(node.Id, node.Label, node.Category);915 newNode.Merge(node);916 }917 foreach (var link in other.InternalLinks.Values)918 {919 var source = this.GetOrCreateNode(link.Source.Id, link.Source.Label, link.Source.Category);920 var target = this.GetOrCreateNode(link.Target.Id, link.Target.Label, link.Target.Category);921 int? index = null;922 if (link.Index.HasValue)923 {924 // ouch, link indexes cannot be compared across Graph instances, we need to assign a new index here.925 string key = string.Format("{0}->{1}({2})", source.Id, target.Id, link.Index.Value);926 string linkId = other.InternalAllocatedLinkIds[key];927 index = this.GetUniqueLinkIndex(source, target, linkId);928 }929 var newLink = this.GetOrCreateLink(source, target, index, link.Label, link.Category);930 newLink.Merge(link);931 }932 }933 }934 /// <summary>935 /// A Node of a Graph.936 /// </summary>937 [DataContract]938 public class GraphObject939 {940 /// <summary>941 /// Optional list of attributes for the node.942 /// </summary>943 [DataMember]944 public Dictionary<string, string> Attributes { get; internal set; }945 /// <summary>946 /// Optional list of attributes that have a multi-part value.947 /// </summary>948 [DataMember]949 public Dictionary<string, HashSet<string>> AttributeLists { get; internal set; }950 /// <summary>951 /// Add an attribute to the node.952 /// </summary>953 public void AddAttribute(string name, string value)954 {955 if (this.Attributes is null)956 {957 this.Attributes = new Dictionary<string, string>();958 }959 this.Attributes[name] = value;960 }961 /// <summary>962 /// Creates a compound attribute value containing a merged list of unique values.963 /// </summary>964 /// <param name="key">The attribute name.</param>965 /// <param name="value">The new value to add to the unique list.</param>966 public int AddListAttribute(string key, string value)967 {968 if (this.AttributeLists is null)969 {970 this.AttributeLists = new Dictionary<string, HashSet<string>>();971 }972 if (!this.AttributeLists.TryGetValue(key, out HashSet<string> list))973 {974 list = new HashSet<string>();975 this.AttributeLists[key] = list;976 }977 list.Add(value);978 return list.Count;979 }980 internal void WriteAttributes(TextWriter writer)981 {982 if (this.Attributes != null)983 {984 List<string> names = new List<string>(this.Attributes.Keys);985 names.Sort(StringComparer.Ordinal); // creates a more stable output file (can be handy for expected output during testing).986 foreach (string name in names)987 {988 var value = this.Attributes[name];989 writer.Write(" {0}='{1}'", name, value);990 }991 }992 if (this.AttributeLists != null)993 {994 List<string> names = new List<string>(this.AttributeLists.Keys);995 names.Sort(StringComparer.Ordinal); // creates a more stable output file (can be handy for expected output during testing).996 foreach (string name in names)997 {998 var value = this.AttributeLists[name];999 writer.Write(" {0}='{1}'", name, string.Join(",", value));1000 }1001 }1002 }1003 internal void Merge(GraphObject other)1004 {1005 if (other.Attributes != null)1006 {1007 foreach (var key in other.Attributes.Keys)1008 {1009 this.AddAttribute(key, other.Attributes[key]);1010 }1011 }1012 if (other.AttributeLists != null)1013 {1014 foreach (var key in other.AttributeLists.Keys)1015 {1016 foreach (var value in other.AttributeLists[key])1017 {...

Full Screen

Full Screen

TestingEngine.cs

Source:TestingEngine.cs Github

copy

Full Screen

...591 {592 TestReport report = new TestReport(this.Configuration);593 runtime.PopulateTestReport(report);594 var coverageInfo = runtime.DefaultActorExecutionContext.BuildCoverageInfo();595 report.CoverageInfo.Merge(coverageInfo);596 this.TestReport.Merge(report);597 // Save the DGML graph of the execution path explored in the last iteration.598 this.LastExecutionGraph = runtime.DefaultActorExecutionContext.GetExecutionGraph();599 }600 /// <summary>601 /// Tracks anonymized telemetry data.602 /// </summary>603 private void TrackTelemetry()604 {605 bool isReplaying = this.Scheduler.IsReplaying;606 TelemetryClient.TrackEvent(isReplaying ? "replay" : "test");607 if (Debugger.IsAttached)608 {609 TelemetryClient.TrackEvent(isReplaying ? "replay-debug" : "test-debug");610 }...

Full Screen

Full Screen

Merge

Using AI Code Generation

copy

Full Screen

1using Microsoft.Coyote.Actors.Coverage;2using System;3using System.Collections.Generic;4using System.Linq;5using System.Text;6using System.Threading.Tasks;7{8 {9 static void Main(string[] args)10 {11 ActorRuntimeLogGraphBuilder builder = new ActorRuntimeLogGraphBuilder();12 builder.Merge(@"C:\Users\user\Documents\Visual Studio 2017\Projects\CoyoteTest\CoyoteTest\bin\Debug\log1.xml");13 builder.Merge(@"C:\Users\user\Documents\Visual Studio 2017\Projects\CoyoteTest\CoyoteTest\bin\Debug\log2.xml");14 builder.Merge(@"C:\Users\user\Documents\Visual Studio 2017\Projects\CoyoteTest\CoyoteTest\bin\Debug\log3.xml");15 builder.Merge(@"C:\Users\user\Documents\Visual Studio 2017\Projects\CoyoteTest\CoyoteTest\bin\Debug\log4.xml");16 builder.Merge(@"C:\Users\user\Documents\Visual Studio 2017\Projects\CoyoteTest\CoyoteTest\bin\Debug\log5.xml");17 builder.Merge(@"C:\Users\user\Documents\Visual Studio 2017\Projects\CoyoteTest\CoyoteTest\bin\Debug\log6.xml");18 builder.Merge(@"C:\Users\user\Documents\Visual Studio 2017\Projects\CoyoteTest\CoyoteTest\bin\Debug\log7.xml");19 builder.Merge(@"C:\Users\user\Documents\Visual Studio 2017\Projects\CoyoteTest\CoyoteTest\bin\Debug\log8.xml");20 builder.Merge(@"C:\Users\user\Documents\Visual Studio 2017\Projects\CoyoteTest\CoyoteTest\bin\Debug\log9.xml");21 builder.Merge(@"C:\Users\user\Documents\Visual Studio 2017\Projects\CoyoteTest\CoyoteTest\bin\Debug\log10.xml");22 builder.Merge(@"C:\Users\user\Documents\Visual Studio 2017\Projects\CoyoteTest\CoyoteTest\bin\Debug\log11.xml");23 builder.Merge(@"C:\Users\user\Documents\Visual Studio 2017\Projects\CoyoteTest\CoyoteTest\bin\Debug\log

Full Screen

Full Screen

Merge

Using AI Code Generation

copy

Full Screen

1using System;2using System.Collections.Generic;3using System.Linq;4using Microsoft.Coyote.Actors.Coverage;5using Microsoft.Coyote.Actors.Coverage.Strategies;6using Microsoft.Coyote.Actors.Coverage.Strategies.GraphCoverage;7{8 {9 static void Main(string[] args)10 {11 var graphBuilder = new ActorRuntimeLogGraphBuilder();12 var strategy = new GraphCoverageStrategy();13 var graph = graphBuilder.BuildGraph(strategy, new[] { "log1.json", "log2.json" });14 Console.WriteLine(graph);15 }16 }17}18using System.Collections.Generic;19using System.Linq;20using Microsoft.Coyote.Actors.Coverage;21using Microsoft.Coyote.Actors.Coverage.Strategies;22using Microsoft.Coyote.Actors.Coverage.Strategies.GraphCoverage;23{24 {25 public List<GraphCoverageResult> GetGraphCoverage(List<ActorRuntimeLogGraph> graphs)26 {27 return graphs.Select(x => new GraphCoverageResult(x, x.States.Count, x.Transitions.Count, x.Edges.Count, 100)).ToList();28 }29 }30}31using System;32using System.Collections.Generic;33using System.Linq;34using Microsoft.Coyote.Actors.Coverage;35using Microsoft.Coyote.Actors.Coverage.Strategies;36using Microsoft.Coyote.Actors.Coverage.Strategies.GraphCoverage;37{38 {39 static void Main(string[] args)40 {41 var graphBuilder = new ActorRuntimeLogGraphBuilder();42 var strategy = new MyStrategy();43 var graph = graphBuilder.BuildGraph(strategy, new[] { "log1.json", "log

Full Screen

Full Screen

Merge

Using AI Code Generation

copy

Full Screen

1using System;2using System.IO;3using System.Linq;4using System.Text;5using Microsoft.Coyote.Actors.Coverage;6using Microsoft.Coyote.IO;7using Microsoft.Coyote.Specifications;8using Microsoft.Coyote.SystematicTesting;9using Microsoft.Coyote.SystematicTesting.Coverage;10using Microsoft.Coyote.Tests.Common.Coverage;11using Microsoft.Coyote.Tests.Common.TestingServices;12using Microsoft.Coyote.Tests.Common.Utilities;13using Microsoft.Coyote.Tests.Systematic;14using Microsoft.Coyote.Tests.Systematic.Coverage;15using Microsoft.Coyote.Tests.Systematic.Strategies;16using Microsoft.Coyote.Tests.Systematic.TestingServices;17using Microsoft.Coyote.Tests.Systematic.Threading;18using Microsoft.Coyote.Tests.Systematic.Threading.Tasks;19using Microsoft.Coyote.Tests.Systematic.Threading.Tasks.Coverage;20using Microsoft.Coyote.Tests.Systematic.Threading.Tasks.Coverage.Strategies;21using Microsoft.Coyote.Tests.Systematic.Threading.Tasks.Coverage.TestingServices;22using Microsoft.Coyote.Tests.Systematic.Threading.Tasks.Coverage.TestingServices.Strategies;23using Microsoft.Coyote.Tests.Systematic.Threading.Tasks.Coverage.Utilities;24using Microsoft.Coyote.Tests.Systematic.Threading.Tasks.Coverage.Utilities.Strategies;25using Microsoft.Coyote.Tests.Systematic.Threading.Tasks.TestingServices;26using Microsoft.Coyote.Tests.Systematic.Threading.Tasks.Utilities;27using Microsoft.Coyote.Tests.Systematic.Threading.Tasks.Utilities.Strategies;28using Microsoft.Coyote.Tests.Systematic.Threading.TestingServices;29using Microsoft.Coyote.Tests.Systematic.Threading.Utilities;30using Microsoft.Coyote.Tests.Systematic.Threading.Utilities.Strategies;31using Microsoft.Coyote.Tests.Systematic.Timers;32using Microsoft.Coyote.Tests.Systematic.Timers.Coverage;33using Microsoft.Coyote.Tests.Systematic.Timers.Coverage.TestingServices;34using Microsoft.Coyote.Tests.Systematic.Timers.TestingServices;35using Microsoft.Coyote.Tests.Systematic.Timers.Utilities;36using Microsoft.Coyote.Tests.Systematic.Timers.Utilities.Strategies;37using Microsoft.Coyote.Tests.Systematic.Timers.Utilities.TestingServices;38using Microsoft.Coyote.Tests.Systematic.Timers.Utilities.TestingServices.Strategies;39using Microsoft.Coyote.Tests.Systematic.Timers.Utilities.TestingServices.Utilities;40using Microsoft.Coyote.Tests.Systematic.Timers.Utilities.TestingServices.Utilities.Strategies;41using Microsoft.Coyote.Tests.Systematic.Timers.Utilities.Utilities;

Full Screen

Full Screen

Merge

Using AI Code Generation

copy

Full Screen

1using System;2using System.IO;3using System.Reflection;4using Microsoft.Coyote.Actors;5using Microsoft.Coyote.Actors.Coverage;6{7 {8 public static void Main(string[] args)9 {10 var graphBuilder = new ActorRuntimeLogGraphBuilder();11 var logDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);12 graphBuilder.Merge(logDir, "CoyoteTest");13 graphBuilder.Save("CoyoteTest", "CoyoteTest");14 }15 }16}17public void Merge(string logDir, string assemblyName)18public void Save(string assemblyName, string graphName)

Full Screen

Full Screen

Merge

Using AI Code Generation

copy

Full Screen

1using System;2using System.IO;3using System.Threading.Tasks;4using Microsoft.Coyote.Actors;5using Microsoft.Coyote.Actors.Coverage;6using Microsoft.Coyote.SystematicTesting;7using Microsoft.Coyote.SystematicTesting.Coverage;8using Microsoft.Coyote.Tests.Common;9using Microsoft.Coyote.Tests.Common.Coverage;10using Microsoft.Coyote.Tests.Common.Runtime;11using Microsoft.Coyote.Tests.Common.SystematicTesting;12using Microsoft.Coyote.Tests.Common.TestingServices;13using Microsoft.Coyote.Tests.Common.Utilities;14using Microsoft.Coyote.Tests.SystematicTesting;15using Xunit;16using Xunit.Abstractions;17{18 {19 public MergeTest(ITestOutputHelper output)20 : base(output)21 {22 }23 [Fact(Timeout = 5000)]24 public void TestMerge()25 {26 var runtimeLogGraphBuilder = new ActorRuntimeLogGraphBuilder();27 var runtimeLogGraphBuilder2 = new ActorRuntimeLogGraphBuilder();28 var runtimeLogGraphBuilder3 = new ActorRuntimeLogGraphBuilder();29 var runtimeLogGraphBuilder4 = new ActorRuntimeLogGraphBuilder();30 var runtimeLogGraphBuilder5 = new ActorRuntimeLogGraphBuilder();31 var runtimeLogGraphBuilder6 = new ActorRuntimeLogGraphBuilder();32 var runtimeLogGraphBuilder7 = new ActorRuntimeLogGraphBuilder();33 var runtimeLogGraphBuilder8 = new ActorRuntimeLogGraphBuilder();34 var runtimeLogGraphBuilder9 = new ActorRuntimeLogGraphBuilder();35 var runtimeLogGraphBuilder10 = new ActorRuntimeLogGraphBuilder();36 runtimeLogGraphBuilder.AddRuntimeLog("C:\\Users\\moham\\Desktop\\log1.json");37 runtimeLogGraphBuilder2.AddRuntimeLog("C:\\Users\\moham\\Desktop\\log2.json");38 runtimeLogGraphBuilder3.AddRuntimeLog("C:\\Users\\moham\\Desktop\\log3.json");39 runtimeLogGraphBuilder4.AddRuntimeLog("C:\\Users\\moham\\Desktop\\log4.json");40 runtimeLogGraphBuilder5.AddRuntimeLog("C:\\Users\\moham\\Desktop\\log5.json");41 runtimeLogGraphBuilder6.AddRuntimeLog("C:\\Users\\moham\\Desktop\\log6.json");42 runtimeLogGraphBuilder7.AddRuntimeLog("C:\\

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful