public void TestHiPrioritySend() { string name = Guid.NewGuid().ToString(); // Create the shared memory buffer SharedMemory readSharedMemory = new SharedMemory ( name, SharedMemoryType.ReadOnly, true ); SharedMemory writeSharedMemory = new SharedMemory ( name, SharedMemoryType.WriteOnly, true ); DualQueue <LocalCallDescriptor> queue = new DualQueue <LocalCallDescriptor>(); DualQueue <LocalCallDescriptor> hiPriQueue = new DualQueue <LocalCallDescriptor>(); int numberOfEvents = 20; LocalCallDescriptorForPostLoggingMessagesToHost LargeLogEvent = CreatePostMessageCallDescriptor(numberOfEvents); queue.Enqueue(LargeLogEvent); LocalCallDescriptorForPostStatus nodeStatusExcept = new LocalCallDescriptorForPostStatus(new NodeStatus(new Exception("I am bad"))); hiPriQueue.Enqueue(nodeStatusExcept); writeSharedMemory.Write(queue, hiPriQueue, true); IList localCallDescriptorList = readSharedMemory.Read(); Assert.IsTrue(localCallDescriptorList.Count == 2); VerifyNodeStatus2((LocalCallDescriptorForPostStatus)localCallDescriptorList[0]); VerifyPostMessagesToHost((LocalCallDescriptorForPostLoggingMessagesToHost)localCallDescriptorList[1], numberOfEvents); writeSharedMemory.Reset(); readSharedMemory.Reset(); readSharedMemory = null; writeSharedMemory = null; }
public void TestLargeSharedMemorySend() { string name = Guid.NewGuid().ToString(); // Create the shared memory buffer SharedMemory readSharedMemory = new SharedMemory ( name, SharedMemoryType.ReadOnly, true ); SharedMemory writeSharedMemory = new SharedMemory ( name, SharedMemoryType.WriteOnly, true ); DualQueue <LocalCallDescriptor> queue = new DualQueue <LocalCallDescriptor>(); DualQueue <LocalCallDescriptor> hiPriQueue = new DualQueue <LocalCallDescriptor>(); int numberOfEvents = 2500; LocalCallDescriptorForPostLoggingMessagesToHost LargeLogEvent = CreatePostMessageCallDescriptor(numberOfEvents); queue.Enqueue(LargeLogEvent); writeSharedMemory.Write(queue, hiPriQueue, false); IList localCallDescriptorList = readSharedMemory.Read(); while (localCallDescriptorList == null || localCallDescriptorList.Count == 0) { writeSharedMemory.Write(queue, hiPriQueue, false); localCallDescriptorList = readSharedMemory.Read(); } VerifyPostMessagesToHost((LocalCallDescriptorForPostLoggingMessagesToHost)localCallDescriptorList[0], numberOfEvents); writeSharedMemory.Reset(); readSharedMemory.Reset(); readSharedMemory = null; writeSharedMemory = null; }
public void TestQueueEnqueueMultipleWriterOneReader() { // Queue which will contain elements added using a single Enqueue per item DualQueue <string> stringQueue = new DualQueue <string>(); // Queue which will contain elements added using an EnqueueArray for a group of Items DualQueue <string> stringQueueTwo = new DualQueue <string>(); // List of strings which are supposed to be in the queue List <string> stringsSupposedToBeInQueue = new List <string>(); // List of strings which are supposed to be in the queue which uses EnQueueArray List <string> stringsSupposedToBeInQueueTwo = new List <string>(); // Array containing our set of ManualResetEvents which is the number of threads we are going to use ManualResetEvent[] waitHandles = new ManualResetEvent[50]; for (int i = 0; i < waitHandles.Length; i++) { waitHandles[i] = new ManualResetEvent(false); ThreadPool.QueueUserWorkItem( delegate(object state) { // Create three non repeating strings to put in the the different queues string string1 = System.Guid.NewGuid().ToString(); string string2 = System.Guid.NewGuid().ToString(); string string3 = System.Guid.NewGuid().ToString(); stringQueue.Enqueue(string1); lock (stringsSupposedToBeInQueue) { stringsSupposedToBeInQueue.Add(string1); } stringQueueTwo.EnqueueArray(new string[] { string2, string3 }); lock (stringsSupposedToBeInQueueTwo) { stringsSupposedToBeInQueueTwo.Add(string2); stringsSupposedToBeInQueueTwo.Add(string3); } // Say we are done the thread ((ManualResetEvent)state).Set(); }, waitHandles[i]); } // Wait for all of the threads to complete foreach (ManualResetEvent resetEvent in waitHandles) { resetEvent.WaitOne(); } // Pop off items from the queue and make sure that we got all of out items back out int numberOfItemsInQueue = 0; string result = null; while ((result = stringQueue.Dequeue()) != null) { Assert.IsTrue(stringsSupposedToBeInQueue.Contains(result), string.Format("Expected {0} to be in the queue but it was not", result)); stringsSupposedToBeInQueue.Remove(result); numberOfItemsInQueue++; } Assert.IsTrue(stringsSupposedToBeInQueue.Count == 0, "Expected all strings to be removed but they were not"); // The number of items we processed should be the same as the number of EnQueues we did Assert.IsTrue(numberOfItemsInQueue == waitHandles.Length, "Expected the number of items in the queue to be the same as the number of Enqueues but it was not"); // Pop off items from the queue and make sure that we got all of out items back out int numberOfItemsInQueueTwo = 0; string result2 = null; while ((result2 = stringQueueTwo.Dequeue()) != null) { Assert.IsTrue(stringsSupposedToBeInQueueTwo.Contains(result2), string.Format("Expected {0} to be in the queue number 2 but it was not", result2)); stringsSupposedToBeInQueueTwo.Remove(result2); numberOfItemsInQueueTwo++; } Assert.IsTrue(stringsSupposedToBeInQueueTwo.Count == 0, "Expected all strings to be removed in queue 2 but they were not"); // The number of items we processed should be the same as the number of EnQueues we did Assert.IsTrue(numberOfItemsInQueueTwo == waitHandles.Length * 2, "Expected the number of items in the queue 2 to be the same as the number of Enqueues but it was not"); // Clear the queue stringQueue.Clear(); Assert.IsTrue(stringQueue.Count == 0, "The count should be zero after clearing the queue"); }
/// <summary> /// Serialize the first object in the queue to the a memory stream which will be copied into shared memory. /// The write stream which is being written to is not the shared memory itself, it is a memory stream from which /// bytes will be copied and placed in the shared memory in the write method. /// </summary> private void SerializeCallDescriptorToStream(DualQueue<LocalCallDescriptor> objectsToWrite) { // Get the object by peeking at the queue rather than dequeueing the object. This is done // because we only want to dequeue the object when it has completely been put in shared memory. // This may be done right away if the object is small enough to fit in the shared memory or // may happen after a the object is sent as a number of smaller chunks. object objectToWrite = objectsToWrite.Peek(); Debug.Assert(objectToWrite != null, "Expect to get a non-null object from the queue"); if (objectToWrite is LocalCallDescriptorForPostBuildResult) { writeStream.WriteByte((byte)ObjectType.PostBuildResult); ((LocalCallDescriptorForPostBuildResult)objectToWrite).WriteToStream(binaryWriter); } else if (objectToWrite is LocalCallDescriptorForPostBuildRequests) { writeStream.WriteByte((byte)ObjectType.PostBuildRequests); ((LocalCallDescriptorForPostBuildRequests)objectToWrite).WriteToStream(binaryWriter); } else if (objectToWrite is LocalCallDescriptorForPostLoggingMessagesToHost) { writeStream.WriteByte((byte)ObjectType.PostLoggingMessagesToHost); ((LocalCallDescriptorForPostLoggingMessagesToHost)objectToWrite).WriteToStream(binaryWriter, loggingTypeCache); } else if (objectToWrite is LocalCallDescriptorForInitializeNode) { writeStream.WriteByte((byte)ObjectType.InitializeNode); ((LocalCallDescriptorForInitializeNode)objectToWrite).WriteToStream(binaryWriter); } else if (objectToWrite is LocalCallDescriptorForInitializationComplete) { writeStream.WriteByte((byte)ObjectType.InitializationComplete); ((LocalCallDescriptorForInitializationComplete)objectToWrite).WriteToStream(binaryWriter); } else if (objectToWrite is LocalCallDescriptorForUpdateNodeSettings) { writeStream.WriteByte((byte)ObjectType.UpdateNodeSettings); ((LocalCallDescriptorForUpdateNodeSettings)objectToWrite).WriteToStream(binaryWriter); } else if (objectToWrite is LocalCallDescriptorForRequestStatus) { writeStream.WriteByte((byte)ObjectType.RequestStatus); ((LocalCallDescriptorForRequestStatus)objectToWrite).WriteToStream(binaryWriter); } else if (objectToWrite is LocalCallDescriptorForPostingCacheEntriesToHost) { writeStream.WriteByte((byte)ObjectType.PostCacheEntriesToHost); ((LocalCallDescriptorForPostingCacheEntriesToHost)objectToWrite).WriteToStream(binaryWriter); } else if (objectToWrite is LocalCallDescriptorForGettingCacheEntriesFromHost) { writeStream.WriteByte((byte)ObjectType.GetCacheEntriesFromHost); ((LocalCallDescriptorForGettingCacheEntriesFromHost)objectToWrite).WriteToStream(binaryWriter); } else if (objectToWrite is LocalCallDescriptorForShutdownComplete) { writeStream.WriteByte((byte)ObjectType.ShutdownComplete); ((LocalCallDescriptorForShutdownComplete)objectToWrite).WriteToStream(binaryWriter); } else if (objectToWrite is LocalCallDescriptorForShutdownNode) { writeStream.WriteByte((byte)ObjectType.ShutdownNode); ((LocalCallDescriptorForShutdownNode)objectToWrite).WriteToStream(binaryWriter); } else if (objectToWrite is LocalCallDescriptorForPostIntrospectorCommand) { writeStream.WriteByte((byte)ObjectType.PostIntrospectorCommand); ((LocalCallDescriptorForPostIntrospectorCommand)objectToWrite).WriteToStream(binaryWriter); } else if (objectToWrite is LocalReplyCallDescriptor) { writeStream.WriteByte((byte)ObjectType.GenericSingleObjectReply); ((LocalReplyCallDescriptor)objectToWrite).WriteToStream(binaryWriter); } else if (objectToWrite is LocalCallDescriptorForPostStatus) { writeStream.WriteByte((byte)ObjectType.PostStatus); ((LocalCallDescriptorForPostStatus)objectToWrite).WriteToStream(binaryWriter); } else { // If the object is not one of the well known local descriptors, use .net Serialization to serialize the object writeStream.WriteByte((byte)ObjectType.NetSerialization); binaryFormatter.Serialize(writeStream, objectToWrite); } }
/// <summary> /// This function write out a set of objects into the the shared buffer. /// In normal operation all the objects in the queue are serialized into /// the buffer followed by an end marker class. If the buffer is not big /// enough to contain a single object the object is broken into into /// multiple buffers as follows - first a frame marker is sent containing /// the size of the serialized object + size of end marker. The reader makes /// sure upon receiving the frame marker that its buffer is large enough /// to contain the object about to be sent. After the frame marker the object /// is sent as a series of buffers until all of it is written out. /// </summary> /// <param name="objectsToWrite"> Queue of objects to be sent (mostly logging messages)</param> /// <param name="objectsToWriteHiPriority">Queue of high priority objects (these are commands and statuses) </param> /// <param name="blockUntilDone"> If true the function will block until both queues are empty</param> internal void Write(DualQueue<LocalCallDescriptor> objectsToWrite, DualQueue<LocalCallDescriptor> objectsToWriteHiPriority, bool blockUntilDone) { Debug.Assert(type == SharedMemoryType.WriteOnly, "Should only be calling Write from a writeonly shared memory object"); lock (writeLock) { // Loop as long as there are objects availiable and room in the shared memory. // If blockUntilDone is set continue to loop until all of the objects in both queues are sent. while ((objectsToWrite.Count > 0 || objectsToWriteHiPriority.Count > 0) && ((blockUntilDone && notFullFlag.WaitOne()) || !IsFull)) { bool isFull = false; long writeStartPosition = writeStream.Position; bool writeEndMarker = false; // Put as many LocalCallDescriptor objects as possible into the shared memory while (!isFull && (objectsToWrite.Count > 0 || objectsToWriteHiPriority.Count > 0)) { long writeResetPosition = writeStream.Position; DualQueue<LocalCallDescriptor> currentQueue = objectsToWriteHiPriority.Count > 0 ? objectsToWriteHiPriority : objectsToWrite; // writeBytesRemaining == 0 is when we are currently not sending a multi part object through // the shared memory if (writeBytesRemaining == 0) { // Serialize the object to the memory stream SerializeCallDescriptorToStream(currentQueue); // If the size of the serialized object plus the end marker fits within the shared memory // dequeue the object as it is going to be sent. if ((writeStream.Position + sizeof(byte)) <= size) { currentQueue.Dequeue(); writeEndMarker = true; } else { // The serialized object plus the end marker is larger than the shared memory buffer // Check if it necessary break down the object into multiple buffers // If the memoryStream was empty before trying to serialize the object // create a frame marker with the size of the object and send through the shared memory if (writeResetPosition == 0) { // We don't want to switch from low priority to high priority queue in the middle of sending a large object // so we make a record of which queue contains the large object largeObjectsQueue = currentQueue; // Calculate the total number of bytes that needs to be sent writeBytesRemaining = (int)(writeStream.Position + sizeof(byte)); // Send a frame marker out to the reader containing the size of the object writeStream.Position = 0; // Write the frameMarkerId byte and then the amount of bytes for the large object writeStream.WriteByte((byte)ObjectType.FrameMarker); binaryWriter.Write((Int32)writeBytesRemaining); writeEndMarker = true; } else { // Some items were placed in the shared Memory buffer, erase the last one which was too large // and say the buffer is full so it can be sent writeStream.Position = writeResetPosition; } isFull = true; } } else { if (writeStream.Position == 0) { // Serialize the object which will be split across multiple buffers SerializeCallDescriptorToStream(largeObjectsQueue); writeStream.WriteByte((byte)ObjectType.EndMarker); } break; } } // If a multi-buffer object is being sent and the large object is still larger or equal to the shard memory buffer - send the next chunk of the object if (writeBytesRemaining != 0 && writeStream.Position >= size) { // Set write Length to an entire buffer length or just the remaining portion int writeLength = writeBytesRemaining > size ? size : writeBytesRemaining; //Write the length of the buffer to the memory file Marshal.WriteInt32((IntPtr)pageFileView, (int)writeLength); Marshal.Copy ( writeStream.GetBuffer(), // Source Buffer (int)(writeStream.Position - writeBytesRemaining), // Start index (IntPtr)((int)pageFileView + 4), //Destination (+4 because of the int written to the memory file with the write length) (int)writeLength // Length of bytes to write ); writeBytesRemaining = writeBytesRemaining - writeLength; IncrementUnreadBatchCounter(); // Once the object is fully sent - remove it from the queue if (writeBytesRemaining == 0) { largeObjectsQueue.Dequeue(); } isFull = true; } if (writeEndMarker) { writeStream.WriteByte((byte)ObjectType.EndMarker); // Need to verify the WriteInt32 and ReadInt32 are always atomic operations //writeSizeMutex.WaitOne(); // Write the size of the buffer to send to the memory stream Marshal.WriteInt32((IntPtr)pageFileView, (int)writeStream.Position); //writeSizeMutex.ReleaseMutex(); Marshal.Copy ( writeStream.GetBuffer(), // Buffer (int)writeStartPosition, // Start Position (IntPtr)((int)pageFileView + writeStartPosition + 4), // Destination + 4 for the int indicating the size of the data to be copied to the memory file (int)(writeStream.Position - writeStartPosition) // Length of data to copy to memory file ); IncrementUnreadBatchCounter(); } if (isFull) { MarkAsFull(); writeStream.SetLength(0); } } } }
public void TestQueueEnqueueMultipleWriterOneReader() { // Queue which will contain elements added using a single Enqueue per item DualQueue<string> stringQueue = new DualQueue<string>(); // Queue which will contain elements added using an EnqueueArray for a group of Items DualQueue<string> stringQueueTwo = new DualQueue<string>(); // List of strings which are supposed to be in the queue List<string> stringsSupposedToBeInQueue = new List<string>(); // List of strings which are supposed to be in the queue which uses EnQueueArray List<string> stringsSupposedToBeInQueueTwo = new List<string>(); // Array containing our set of ManualResetEvents which is the number of threads we are going to use ManualResetEvent[] waitHandles = new ManualResetEvent[50]; for (int i = 0; i < waitHandles.Length; i++) { waitHandles[i] = new ManualResetEvent(false); ThreadPool.QueueUserWorkItem( delegate(object state) { // Create three non repeating strings to put in the the different queues string string1 = System.Guid.NewGuid().ToString(); string string2 = System.Guid.NewGuid().ToString(); string string3 = System.Guid.NewGuid().ToString(); stringQueue.Enqueue(string1); lock (stringsSupposedToBeInQueue) { stringsSupposedToBeInQueue.Add(string1); } stringQueueTwo.EnqueueArray(new string[] { string2, string3 }); lock (stringsSupposedToBeInQueueTwo) { stringsSupposedToBeInQueueTwo.Add(string2); stringsSupposedToBeInQueueTwo.Add(string3); } // Say we are done the thread ((ManualResetEvent)state).Set(); }, waitHandles[i]); } // Wait for all of the threads to complete foreach (ManualResetEvent resetEvent in waitHandles) { resetEvent.WaitOne(); } // Pop off items from the queue and make ture that we got all of out items back out int numberOfItemsInQueue = 0; string result = null; while ((result = stringQueue.Dequeue()) != null) { Assert.IsTrue(stringsSupposedToBeInQueue.Contains(result),string.Format("Expected {0} to be in the queue but it was not",result)); stringsSupposedToBeInQueue.Remove(result); numberOfItemsInQueue++; } Assert.IsTrue(stringsSupposedToBeInQueue.Count == 0, "Expected all strings to be removed but they were not"); // The number of items we processed should be the same as the number of EnQueues we did Assert.IsTrue(numberOfItemsInQueue == waitHandles.Length,"Expected the number of items in the queue to be the same as the number of Enqueues but it was not"); // Pop off items from the queue and make ture that we got all of out items back out int numberOfItemsInQueueTwo = 0; string result2 = null; while ((result2 = stringQueueTwo.Dequeue()) != null) { Assert.IsTrue(stringsSupposedToBeInQueueTwo.Contains(result2), string.Format("Expected {0} to be in the queue number 2 but it was not", result2)); stringsSupposedToBeInQueueTwo.Remove(result2); numberOfItemsInQueueTwo++; } Assert.IsTrue(stringsSupposedToBeInQueueTwo.Count == 0, "Expected all strings to be removed in queue 2 but they were not"); // The number of items we processed should be the same as the number of EnQueues we did Assert.IsTrue(numberOfItemsInQueueTwo == waitHandles.Length*2, "Expected the number of items in the queue 2 to be the same as the number of Enqueues but it was not"); // Clear the queue stringQueue.Clear(); Assert.IsTrue(stringQueue.Count == 0, "The count should be zero after clearing the queue"); }
public void TestItemsInandOutOfSharedMemory() { string name = Guid.NewGuid().ToString(); // Create the shared memory buffer SharedMemory readSharedMemory = new SharedMemory ( name, SharedMemoryType.ReadOnly, true ); SharedMemory writeSharedMemory = new SharedMemory ( name, SharedMemoryType.WriteOnly, true ); DualQueue <LocalCallDescriptor> queue = new DualQueue <LocalCallDescriptor>(); DualQueue <LocalCallDescriptor> hiPriQueue = new DualQueue <LocalCallDescriptor>(); LocalCallDescriptorForPostLoggingMessagesToHost LargeLogEvent = CreatePostMessageCallDescriptor(1); LocalCallDescriptorForUpdateNodeSettings updateNodeSettings = new LocalCallDescriptorForUpdateNodeSettings(true, true, true); LocalCallDescriptorForPostBuildResult buildResult = new LocalCallDescriptorForPostBuildResult(CreateBuildResult()); LocalCallDescriptorForPostBuildRequests buildRequests = new LocalCallDescriptorForPostBuildRequests(CreateBuildRequest()); LocalCallDescriptorForRequestStatus requestStatus = new LocalCallDescriptorForRequestStatus(4); LocalCallDescriptorForPostStatus nodeStatusNoExcept = new LocalCallDescriptorForPostStatus(new NodeStatus(1, true, 2, 3, 4, true)); LocalCallDescriptorForPostStatus nodeStatusExcept = new LocalCallDescriptorForPostStatus(new NodeStatus(new Exception("I am bad"))); LocalCallDescriptorForShutdownNode shutdownNode = new LocalCallDescriptorForShutdownNode(Node.NodeShutdownLevel.BuildCompleteSuccess, true); LocalCallDescriptorForShutdownComplete shutdownComplete = new LocalCallDescriptorForShutdownComplete(Node.NodeShutdownLevel.BuildCompleteFailure, 0); LocalCallDescriptorForInitializationComplete initializeComplete = new LocalCallDescriptorForInitializationComplete(99); BuildPropertyGroup propertyGroup = new BuildPropertyGroup(); BuildProperty propertyToAdd = new BuildProperty("PropertyName", "Value"); propertyGroup.SetProperty(propertyToAdd); CacheEntry[] entries = CreateCacheEntries(); LocalCallDescriptorForGettingCacheEntriesFromHost getCacheEntries = new LocalCallDescriptorForGettingCacheEntriesFromHost(new string[] { "Hi", "Hello" }, "Name", propertyGroup, "3.5", CacheContentType.Properties); LocalCallDescriptorForPostingCacheEntriesToHost postCacheEntries = new LocalCallDescriptorForPostingCacheEntriesToHost(entries, "ScopeName", propertyGroup, "3.5", CacheContentType.BuildResults); LocalReplyCallDescriptor replyDescriptor1 = new LocalReplyCallDescriptor(1, entries); LocalReplyCallDescriptor replyDescriptor2 = new LocalReplyCallDescriptor(6, "Foo"); IDictionary environmentVariables = Environment.GetEnvironmentVariables(); Hashtable environmentVariablesHashtable = new Hashtable(environmentVariables); string className = "Class"; string loggerAssemblyName = "Class"; string loggerFileAssembly = null; string loggerSwitchParameters = "Class"; LoggerVerbosity verbosity = LoggerVerbosity.Detailed; LoggerDescription description = new LoggerDescription(className, loggerAssemblyName, loggerFileAssembly, loggerSwitchParameters, verbosity); LocalCallDescriptorForInitializeNode initializeNode = new LocalCallDescriptorForInitializeNode(environmentVariablesHashtable, new LoggerDescription[] { description }, 4, propertyGroup, ToolsetDefinitionLocations.ConfigurationFile, 5, String.Empty); queue.Enqueue(LargeLogEvent); queue.Enqueue(updateNodeSettings); queue.Enqueue(buildResult); queue.Enqueue(buildRequests); queue.Enqueue(requestStatus); queue.Enqueue(nodeStatusNoExcept); queue.Enqueue(nodeStatusExcept); queue.Enqueue(shutdownNode); queue.Enqueue(shutdownComplete); queue.Enqueue(initializeComplete); queue.Enqueue(getCacheEntries); queue.Enqueue(postCacheEntries); queue.Enqueue(replyDescriptor1); queue.Enqueue(replyDescriptor2); queue.Enqueue(initializeNode); writeSharedMemory.Write(queue, hiPriQueue, false); IList localCallDescriptorList = readSharedMemory.Read(); Assert.IsTrue(localCallDescriptorList.Count == 15); LocalCallDescriptorForPostLoggingMessagesToHost messageCallDescriptor = localCallDescriptorList[0] as LocalCallDescriptorForPostLoggingMessagesToHost; VerifyPostMessagesToHost(messageCallDescriptor, 1); LocalCallDescriptorForUpdateNodeSettings updateSettingsCallDescriptor = localCallDescriptorList[1] as LocalCallDescriptorForUpdateNodeSettings; VerifyUpdateSettings(updateSettingsCallDescriptor); LocalCallDescriptorForPostBuildResult buildResultCallDescriptor = localCallDescriptorList[2] as LocalCallDescriptorForPostBuildResult; CompareBuildResult(buildResultCallDescriptor); LocalCallDescriptorForPostBuildRequests buildRequestsCallDescriptor = localCallDescriptorList[3] as LocalCallDescriptorForPostBuildRequests; ComparebuildRequests(buildRequestsCallDescriptor); LocalCallDescriptorForRequestStatus requestStatusCallDescriptor = localCallDescriptorList[4] as LocalCallDescriptorForRequestStatus; Assert.IsTrue(requestStatusCallDescriptor.RequestId == 4); LocalCallDescriptorForPostStatus nodeStatus1CallDescriptor = localCallDescriptorList[5] as LocalCallDescriptorForPostStatus; VerifyNodeStatus1(nodeStatus1CallDescriptor); LocalCallDescriptorForPostStatus nodeStatus2CallDescriptor = localCallDescriptorList[6] as LocalCallDescriptorForPostStatus; VerifyNodeStatus2(nodeStatus2CallDescriptor); LocalCallDescriptorForShutdownNode shutdownNodeCallDescriptor = localCallDescriptorList[7] as LocalCallDescriptorForShutdownNode; Assert.IsTrue(shutdownNodeCallDescriptor.ShutdownLevel == Node.NodeShutdownLevel.BuildCompleteSuccess); Assert.IsTrue(shutdownNodeCallDescriptor.ExitProcess); LocalCallDescriptorForShutdownComplete shutdownNodeCompleteCallDescriptor = localCallDescriptorList[8] as LocalCallDescriptorForShutdownComplete; Assert.IsTrue(shutdownNodeCompleteCallDescriptor.ShutdownLevel == Node.NodeShutdownLevel.BuildCompleteFailure); LocalCallDescriptorForInitializationComplete initializeCompleteCallDescriptor = localCallDescriptorList[9] as LocalCallDescriptorForInitializationComplete; Assert.IsTrue(initializeCompleteCallDescriptor.ProcessId == 99); LocalCallDescriptorForGettingCacheEntriesFromHost getCacheEntriesCallDescriptor = localCallDescriptorList[10] as LocalCallDescriptorForGettingCacheEntriesFromHost; VerifyGetCacheEntryFromHost(getCacheEntriesCallDescriptor); LocalCallDescriptorForPostingCacheEntriesToHost postCacheEntriesCallDescriptor = localCallDescriptorList[11] as LocalCallDescriptorForPostingCacheEntriesToHost; Assert.IsTrue(string.Compare(postCacheEntriesCallDescriptor.ScopeName, "ScopeName", StringComparison.OrdinalIgnoreCase) == 0); Assert.IsTrue(string.Compare(postCacheEntriesCallDescriptor.ScopeProperties["PropertyName"].Value, "Value", StringComparison.OrdinalIgnoreCase) == 0); Assert.IsTrue(string.Compare(postCacheEntriesCallDescriptor.ScopeToolsVersion, "3.5", StringComparison.OrdinalIgnoreCase) == 0); Assert.IsTrue(postCacheEntriesCallDescriptor.ContentType == CacheContentType.BuildResults); VerifyGetCacheEntries(postCacheEntriesCallDescriptor.Entries); LocalReplyCallDescriptor reply1CallDescriptor = localCallDescriptorList[12] as LocalReplyCallDescriptor; Assert.IsTrue(reply1CallDescriptor.RequestingCallNumber == 1); VerifyGetCacheEntries((CacheEntry[])reply1CallDescriptor.ReplyData); LocalReplyCallDescriptor reply2CallDescriptor = localCallDescriptorList[13] as LocalReplyCallDescriptor; Assert.IsTrue(reply2CallDescriptor.RequestingCallNumber == 6); Assert.IsTrue(string.Compare("Foo", (string)reply2CallDescriptor.ReplyData, StringComparison.OrdinalIgnoreCase) == 0); LocalCallDescriptorForInitializeNode initializeCallDescriptor = localCallDescriptorList[14] as LocalCallDescriptorForInitializeNode; Assert.IsTrue(initializeCallDescriptor.ParentProcessId == 5); Assert.IsTrue(initializeCallDescriptor.NodeId == 4); Assert.IsTrue(initializeCallDescriptor.ToolsetSearchLocations == ToolsetDefinitionLocations.ConfigurationFile); Assert.IsTrue(string.Compare(initializeCallDescriptor.ParentGlobalProperties["PropertyName"].Value, "Value", StringComparison.OrdinalIgnoreCase) == 0); Assert.IsTrue(string.Compare(initializeCallDescriptor.NodeLoggers[0].Name, "Class", StringComparison.OrdinalIgnoreCase) == 0); IDictionary variables = Environment.GetEnvironmentVariables(); Assert.IsTrue(variables.Count == initializeCallDescriptor.EnvironmentVariables.Count); foreach (string key in variables.Keys) { Assert.IsTrue(string.Compare((string)initializeCallDescriptor.EnvironmentVariables[key], (string)variables[key], StringComparison.OrdinalIgnoreCase) == 0); } writeSharedMemory.Reset(); readSharedMemory.Reset(); readSharedMemory = null; writeSharedMemory = null; }
public void TestHiPrioritySend() { string name = Guid.NewGuid().ToString(); // Create the shared memory buffer SharedMemory readSharedMemory = new SharedMemory ( name, SharedMemoryType.ReadOnly, true ); SharedMemory writeSharedMemory = new SharedMemory ( name, SharedMemoryType.WriteOnly, true ); DualQueue<LocalCallDescriptor> queue = new DualQueue<LocalCallDescriptor>(); DualQueue<LocalCallDescriptor> hiPriQueue = new DualQueue<LocalCallDescriptor>(); int numberOfEvents = 20; LocalCallDescriptorForPostLoggingMessagesToHost LargeLogEvent = CreatePostMessageCallDescriptor(numberOfEvents); queue.Enqueue(LargeLogEvent); LocalCallDescriptorForPostStatus nodeStatusExcept = new LocalCallDescriptorForPostStatus(new NodeStatus(new Exception("I am bad"))); hiPriQueue.Enqueue(nodeStatusExcept); writeSharedMemory.Write(queue, hiPriQueue, true); IList localCallDescriptorList = readSharedMemory.Read(); Assert.IsTrue(localCallDescriptorList.Count == 2); VerifyNodeStatus2((LocalCallDescriptorForPostStatus)localCallDescriptorList[0]); VerifyPostMessagesToHost((LocalCallDescriptorForPostLoggingMessagesToHost)localCallDescriptorList[1], numberOfEvents); writeSharedMemory.Reset(); readSharedMemory.Reset(); readSharedMemory = null; writeSharedMemory = null; }
public void TestItemsInandOutOfSharedMemory() { string name = Guid.NewGuid().ToString(); // Create the shared memory buffer SharedMemory readSharedMemory = new SharedMemory ( name, SharedMemoryType.ReadOnly, true ); SharedMemory writeSharedMemory = new SharedMemory ( name, SharedMemoryType.WriteOnly, true ); DualQueue<LocalCallDescriptor> queue = new DualQueue<LocalCallDescriptor>(); DualQueue<LocalCallDescriptor> hiPriQueue = new DualQueue<LocalCallDescriptor>(); LocalCallDescriptorForPostLoggingMessagesToHost LargeLogEvent = CreatePostMessageCallDescriptor(1); LocalCallDescriptorForUpdateNodeSettings updateNodeSettings = new LocalCallDescriptorForUpdateNodeSettings(true, true, true); LocalCallDescriptorForPostBuildResult buildResult = new LocalCallDescriptorForPostBuildResult(CreateBuildResult()); LocalCallDescriptorForPostBuildRequests buildRequests = new LocalCallDescriptorForPostBuildRequests(CreateBuildRequest()); LocalCallDescriptorForRequestStatus requestStatus = new LocalCallDescriptorForRequestStatus(4); LocalCallDescriptorForPostStatus nodeStatusNoExcept = new LocalCallDescriptorForPostStatus(new NodeStatus(1, true, 2, 3, 4, true)); LocalCallDescriptorForPostStatus nodeStatusExcept = new LocalCallDescriptorForPostStatus(new NodeStatus(new Exception("I am bad"))); LocalCallDescriptorForShutdownNode shutdownNode = new LocalCallDescriptorForShutdownNode(Node.NodeShutdownLevel.BuildCompleteSuccess, true); LocalCallDescriptorForShutdownComplete shutdownComplete = new LocalCallDescriptorForShutdownComplete(Node.NodeShutdownLevel.BuildCompleteFailure, 0); LocalCallDescriptorForInitializationComplete initializeComplete = new LocalCallDescriptorForInitializationComplete(99); BuildPropertyGroup propertyGroup = new BuildPropertyGroup(); BuildProperty propertyToAdd = new BuildProperty("PropertyName", "Value"); propertyGroup.SetProperty(propertyToAdd); CacheEntry[] entries = CreateCacheEntries(); LocalCallDescriptorForGettingCacheEntriesFromHost getCacheEntries = new LocalCallDescriptorForGettingCacheEntriesFromHost(new string[] { "Hi", "Hello" }, "Name", propertyGroup, "3.5", CacheContentType.Properties); LocalCallDescriptorForPostingCacheEntriesToHost postCacheEntries = new LocalCallDescriptorForPostingCacheEntriesToHost(entries, "ScopeName", propertyGroup, "3.5", CacheContentType.BuildResults); LocalReplyCallDescriptor replyDescriptor1 = new LocalReplyCallDescriptor(1, entries); LocalReplyCallDescriptor replyDescriptor2 = new LocalReplyCallDescriptor(6, "Foo"); IDictionary environmentVariables = Environment.GetEnvironmentVariables(); Hashtable environmentVariablesHashtable = new Hashtable(environmentVariables); string className = "Class"; string loggerAssemblyName = "Class"; string loggerFileAssembly = null; string loggerSwitchParameters = "Class"; LoggerVerbosity verbosity = LoggerVerbosity.Detailed; LoggerDescription description = new LoggerDescription(className, loggerAssemblyName, loggerFileAssembly, loggerSwitchParameters, verbosity); LocalCallDescriptorForInitializeNode initializeNode = new LocalCallDescriptorForInitializeNode(environmentVariablesHashtable, new LoggerDescription[] { description }, 4, propertyGroup, ToolsetDefinitionLocations.ConfigurationFile, 5, String.Empty); queue.Enqueue(LargeLogEvent); queue.Enqueue(updateNodeSettings); queue.Enqueue(buildResult); queue.Enqueue(buildRequests); queue.Enqueue(requestStatus); queue.Enqueue(nodeStatusNoExcept); queue.Enqueue(nodeStatusExcept); queue.Enqueue(shutdownNode); queue.Enqueue(shutdownComplete); queue.Enqueue(initializeComplete); queue.Enqueue(getCacheEntries); queue.Enqueue(postCacheEntries); queue.Enqueue(replyDescriptor1); queue.Enqueue(replyDescriptor2); queue.Enqueue(initializeNode); writeSharedMemory.Write(queue, hiPriQueue, false); IList localCallDescriptorList = readSharedMemory.Read(); Assert.IsTrue(localCallDescriptorList.Count == 15); LocalCallDescriptorForPostLoggingMessagesToHost messageCallDescriptor = localCallDescriptorList[0] as LocalCallDescriptorForPostLoggingMessagesToHost; VerifyPostMessagesToHost(messageCallDescriptor, 1); LocalCallDescriptorForUpdateNodeSettings updateSettingsCallDescriptor = localCallDescriptorList[1] as LocalCallDescriptorForUpdateNodeSettings; VerifyUpdateSettings(updateSettingsCallDescriptor); LocalCallDescriptorForPostBuildResult buildResultCallDescriptor = localCallDescriptorList[2] as LocalCallDescriptorForPostBuildResult; CompareBuildResult(buildResultCallDescriptor); LocalCallDescriptorForPostBuildRequests buildRequestsCallDescriptor = localCallDescriptorList[3] as LocalCallDescriptorForPostBuildRequests; ComparebuildRequests(buildRequestsCallDescriptor); LocalCallDescriptorForRequestStatus requestStatusCallDescriptor = localCallDescriptorList[4] as LocalCallDescriptorForRequestStatus; Assert.IsTrue(requestStatusCallDescriptor.RequestId == 4); LocalCallDescriptorForPostStatus nodeStatus1CallDescriptor = localCallDescriptorList[5] as LocalCallDescriptorForPostStatus; VerifyNodeStatus1(nodeStatus1CallDescriptor); LocalCallDescriptorForPostStatus nodeStatus2CallDescriptor = localCallDescriptorList[6] as LocalCallDescriptorForPostStatus; VerifyNodeStatus2(nodeStatus2CallDescriptor); LocalCallDescriptorForShutdownNode shutdownNodeCallDescriptor = localCallDescriptorList[7] as LocalCallDescriptorForShutdownNode; Assert.IsTrue(shutdownNodeCallDescriptor.ShutdownLevel == Node.NodeShutdownLevel.BuildCompleteSuccess); Assert.IsTrue(shutdownNodeCallDescriptor.ExitProcess); LocalCallDescriptorForShutdownComplete shutdownNodeCompleteCallDescriptor = localCallDescriptorList[8] as LocalCallDescriptorForShutdownComplete; Assert.IsTrue(shutdownNodeCompleteCallDescriptor.ShutdownLevel == Node.NodeShutdownLevel.BuildCompleteFailure); LocalCallDescriptorForInitializationComplete initializeCompleteCallDescriptor = localCallDescriptorList[9] as LocalCallDescriptorForInitializationComplete; Assert.IsTrue(initializeCompleteCallDescriptor.ProcessId == 99); LocalCallDescriptorForGettingCacheEntriesFromHost getCacheEntriesCallDescriptor = localCallDescriptorList[10] as LocalCallDescriptorForGettingCacheEntriesFromHost; VerifyGetCacheEntryFromHost(getCacheEntriesCallDescriptor); LocalCallDescriptorForPostingCacheEntriesToHost postCacheEntriesCallDescriptor = localCallDescriptorList[11] as LocalCallDescriptorForPostingCacheEntriesToHost; Assert.IsTrue(string.Compare(postCacheEntriesCallDescriptor.ScopeName, "ScopeName", StringComparison.OrdinalIgnoreCase) == 0); Assert.IsTrue(string.Compare(postCacheEntriesCallDescriptor.ScopeProperties["PropertyName"].Value, "Value", StringComparison.OrdinalIgnoreCase) == 0); Assert.IsTrue(string.Compare(postCacheEntriesCallDescriptor.ScopeToolsVersion, "3.5", StringComparison.OrdinalIgnoreCase) == 0); Assert.IsTrue(postCacheEntriesCallDescriptor.ContentType == CacheContentType.BuildResults); VerifyGetCacheEntries(postCacheEntriesCallDescriptor.Entries); LocalReplyCallDescriptor reply1CallDescriptor = localCallDescriptorList[12] as LocalReplyCallDescriptor; Assert.IsTrue(reply1CallDescriptor.RequestingCallNumber == 1); VerifyGetCacheEntries((CacheEntry[])reply1CallDescriptor.ReplyData); LocalReplyCallDescriptor reply2CallDescriptor = localCallDescriptorList[13] as LocalReplyCallDescriptor; Assert.IsTrue(reply2CallDescriptor.RequestingCallNumber == 6); Assert.IsTrue(string.Compare("Foo", (string)reply2CallDescriptor.ReplyData, StringComparison.OrdinalIgnoreCase) == 0); LocalCallDescriptorForInitializeNode initializeCallDescriptor = localCallDescriptorList[14] as LocalCallDescriptorForInitializeNode; Assert.IsTrue(initializeCallDescriptor.ParentProcessId == 5); Assert.IsTrue(initializeCallDescriptor.NodeId == 4); Assert.IsTrue(initializeCallDescriptor.ToolsetSearchLocations == ToolsetDefinitionLocations.ConfigurationFile); Assert.IsTrue(string.Compare(initializeCallDescriptor.ParentGlobalProperties["PropertyName"].Value, "Value", StringComparison.OrdinalIgnoreCase) == 0); Assert.IsTrue(string.Compare(initializeCallDescriptor.NodeLoggers[0].Name, "Class", StringComparison.OrdinalIgnoreCase) == 0); IDictionary variables = Environment.GetEnvironmentVariables(); Assert.IsTrue(variables.Count == initializeCallDescriptor.EnvironmentVariables.Count); foreach (string key in variables.Keys) { Assert.IsTrue(string.Compare((string)initializeCallDescriptor.EnvironmentVariables[key], (string)variables[key], StringComparison.OrdinalIgnoreCase) == 0); } writeSharedMemory.Reset(); readSharedMemory.Reset(); readSharedMemory = null; writeSharedMemory = null; }
public void TestLargeSharedMemorySend() { string name = Guid.NewGuid().ToString(); // Create the shared memory buffer SharedMemory readSharedMemory = new SharedMemory ( name, SharedMemoryType.ReadOnly, true ); SharedMemory writeSharedMemory = new SharedMemory ( name, SharedMemoryType.WriteOnly, true ); DualQueue<LocalCallDescriptor> queue = new DualQueue<LocalCallDescriptor>(); DualQueue<LocalCallDescriptor> hiPriQueue = new DualQueue<LocalCallDescriptor>(); int numberOfEvents = 2500; LocalCallDescriptorForPostLoggingMessagesToHost LargeLogEvent = CreatePostMessageCallDescriptor(numberOfEvents); queue.Enqueue(LargeLogEvent); writeSharedMemory.Write(queue, hiPriQueue, false); IList localCallDescriptorList = readSharedMemory.Read(); while (localCallDescriptorList == null || localCallDescriptorList.Count == 0) { writeSharedMemory.Write(queue, hiPriQueue, false); localCallDescriptorList = readSharedMemory.Read(); } VerifyPostMessagesToHost((LocalCallDescriptorForPostLoggingMessagesToHost)localCallDescriptorList[0], numberOfEvents); writeSharedMemory.Reset(); readSharedMemory.Reset(); readSharedMemory = null; writeSharedMemory = null; }
/// <summary> /// Constructor to init all data except for BinPath which is initialized separately because /// a parameterless constructor is needed for COM interop /// </summary> internal Engine ( int numberOfCpus, bool isChildNode, int parentNodeId, string localNodeProviderParameters, BuildPropertyGroup globalProperties, ToolsetDefinitionLocations locations ) { // No need to check whether locations parameter // is null, because it is a value type this.startupDirectory = Environment.CurrentDirectory; this.engineGlobalProperties = globalProperties == null ? new BuildPropertyGroup() : globalProperties; this.environmentProperties = new BuildPropertyGroup(); this.toolsetStateMap = new Dictionary<string, ToolsetState>(StringComparer.OrdinalIgnoreCase); this.toolsets = new ToolsetCollection(this); // Every environment variable can be referenced just like a property // from the project file. Here, we go ahead and add all the environment // variables to the property bag, so they can be treated just like any // other property later on. this.environmentProperties.GatherEnvironmentVariables(); this.projectsLoadedByHost = new Hashtable(StringComparer.OrdinalIgnoreCase); this.cacheOfBuildingProjects = new ProjectManager(); this.eventSource = new EventSource(); this.buildEnabled = true; this.flushRequestEvent = new ManualResetEvent(false); this.primaryLoggingServices = new EngineLoggingServicesInProc(eventSource, false, flushRequestEvent); // Read any toolsets from the registry and config file PopulateToolsetStateMap(locations); this.nodeId = parentNodeId; this.localNodeProviderParameters = localNodeProviderParameters; this.numberOfCpus = numberOfCpus; if (this.numberOfCpus == 1 && !isChildNode) { this.primaryLoggingServices.FlushBuildEventsImmediatly = true; } this.buildRequests = new DualQueue<BuildRequest>(); this.taskOutputUpdates = new DualQueue<TaskExecutionContext>(); this.engineCommands = new DualQueue<EngineCommand>(); this.engineCallback = new EngineCallback(this); this.nodeManager = new NodeManager(this.numberOfCpus, isChildNode, this); this.scheduler = new Scheduler(this.nodeId, this); this.router = new Router(this, scheduler); this.cacheManager = new CacheManager(this.DefaultToolsVersion); this.lastUsedLoggerId = EngineLoggingServicesInProc.FIRST_AVAILABLE_LOGGERID; this.enabledCentralLogging = false; this.introspector = new Introspector(this, cacheOfBuildingProjects, nodeManager); // Initialize the node provider InitializeLocalNodeProvider(locations); }