public void WindowsIdMappingTest() { Utils.CheckTimeDrift(Fixture, Output); // Disconnect from the PISERVER Output.WriteLine($"Disconnect from PI Server [{Fixture.PIServer}]."); Fixture.PIServer.Disconnect(); AFTime startTime = AFTime.Now.ToPIPrecision(); string startTimePI = PIDAUtilities.ToPiTimeString(startTime.LocalTime); // Connect again to check for the logs for identity used to get into PISERVER Output.WriteLine($"Reconnect to PI Server [{Fixture.PIServer}]."); Fixture.PIServer.Connect(); // window of time to check for logged messages AFTime endTime = startTime + TimeSpan.FromMinutes(5); string endTimePI = PIDAUtilities.ToPiTimeString(endTime.LocalTime); int expectedMsgID = 7082; Output.WriteLine($"Check if user is logged in through Windows Login."); AssertEventually.True(() => { // Checks for windows login five times return(PIDAUtilities.FindMessagesInLog(Fixture, startTimePI, endTimePI, expectedMsgID, "*Method: Windows Login*")); }, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(3), "Windows login not found."); }
public void PIPointSearchTest() { PIServer piServer = PIFixture.PIServer; int numberOfPointsToCreate = 10; var pointPrefix = "PIPointSearchTest_Point"; try { // Create PI Points Output.WriteLine($"Creating PI Points with prefix [{pointPrefix}]."); var points = PIFixture.CreatePIPoints($"{pointPrefix}#", numberOfPointsToCreate); // Assign range of values to defined tags for (int i = 0; i < points.Count(); i++) { points.ElementAt(i).UpdateValue(new AFValue(Math.Pow(-1, i + 1), null), 0); // Set the Step attribute of half of the PI Points to true and half to false points.ElementAt(i).SetAttribute(PICommonPointAttributes.Step, Convert.ToBoolean(1 * ((i + 1) % 2))); points.ElementAt(i).SaveAttributes(); } // Search PI Points with queries var searchQuery = $"Name:'{pointPrefix}*' value:>0"; Output.WriteLine($"Searching for PI Points with query [{searchQuery}]."); var parsedQuery = PIPointQuery.ParseQuery(piServer, searchQuery); var searchPointsCount = PIPoint.FindPIPoints(piServer, parsedQuery).Count(); AssertEventually.True( () => PIPoint.FindPIPoints(piServer, parsedQuery).Count() == (numberOfPointsToCreate / 2), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(0.5), $"The PI Points count do not match. Expected: {numberOfPointsToCreate / 2}, Actual: {searchPointsCount}."); searchQuery = $"Name:'{pointPrefix}*'"; Output.WriteLine($"Searching for PI Points with query [{searchQuery}]."); parsedQuery = PIPointQuery.ParseQuery(piServer, searchQuery); searchPointsCount = PIPoint.FindPIPoints(piServer, parsedQuery).Count(); AssertEventually.True( () => PIPoint.FindPIPoints(piServer, parsedQuery).Count() == numberOfPointsToCreate, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(0.5), $"The PI Points count do not match. Expected: {numberOfPointsToCreate}, Actual: {searchPointsCount}."); searchQuery = $"Name:'{pointPrefix}*' step:=0"; Output.WriteLine($"Searching for PI Points with query [{searchQuery}]."); parsedQuery = PIPointQuery.ParseQuery(piServer, searchQuery); searchPointsCount = PIPoint.FindPIPoints(piServer, parsedQuery).Count(); AssertEventually.True( () => PIPoint.FindPIPoints(piServer, parsedQuery).Count() == (numberOfPointsToCreate / 2), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(0.5), $"The PI Points count do not match. Expected: {numberOfPointsToCreate / 2}, Actual: {searchPointsCount}."); } finally { PIFixture.DeletePIPoints("PIPointSearchTest_Point*", Output); } }
public void StreamUpdatesTest() { var testStart = DateTime.UtcNow; // Get Data Archive object from PI Web API to extract its WebId var dataArchiveUrl = $"{Fixture.HomePageUrl}/dataservers?path=\\\\PIServers[{Settings.PIDataArchive}]"; Output.WriteLine($"Get Data Archive data through Web API using Url [{dataArchiveUrl}]."); var dataArchiveData = JObject.Parse(Fixture.Client.DownloadString(dataArchiveUrl)); // Verifies test PI Point is found var piPointUrl = $"{Fixture.HomePageUrl}/dataservers/{(string)dataArchiveData["WebId"]}/points?nameFilter={PIPointName}"; Output.WriteLine($"Get PI Point data for [{PIPointName}] through Web API using Url [{piPointUrl}]."); var piPointData = JObject.Parse(Fixture.Client.DownloadString(piPointUrl)); Assert.True(piPointData["Items"].Count() > 0, $"Could not find test PI Point [{PIPointName}]."); var webId = piPointData["Items"][0]["WebId"].ToString(); var streamUrl = $"{Fixture.HomePageUrl}/streams/{webId}"; var registerUrl = $"{streamUrl}/updates"; var response = Fixture.Client.UploadString(registerUrl, "POST", string.Empty); var registerData = JObject.Parse(response); var marker = (string)registerData["LatestMarker"]; // Wait for value to update from analysis var updatesUrl = $"{Fixture.HomePageUrl}/streams/updates/{marker}"; // Request stream updates using marker every 5 seconds until new events received and verify new value found in updates Output.WriteLine($"Get stream updates through Web API using Url [{updatesUrl}]."); var waitTimeInSeconds = 60; var pollIntervalInSeconds = 5; AssertEventually.True( () => JObject.Parse(Fixture.Client.DownloadString(updatesUrl))["Events"].ToObject <List <JObject> >().Count() > 0, TimeSpan.FromSeconds(waitTimeInSeconds), TimeSpan.FromSeconds(pollIntervalInSeconds), "No new events received via stream updates."); Output.WriteLine($"Verify new value in stream updates."); AssertEventually.True( () => { var updateData = JObject.Parse(Fixture.Client.DownloadString(updatesUrl)); var updateEvents = updateData["Events"].ToObject <List <JObject> >(); var updateEvent = updateEvents.Last(); var timeStamp = (DateTime)updateEvent["Timestamp"]; return(timeStamp > testStart); }, TimeSpan.FromSeconds(waitTimeInSeconds), TimeSpan.FromSeconds(pollIntervalInSeconds), $"Test failed to retrieve a stream updates event with a timestamp after test start time [{testStart}] within {waitTimeInSeconds} seconds. " + $"This may indicate that the data ingress for {PIPointName} to PI Data Archive was delayed, or a longer CalculationWaitTimeInSeconds " + $"has been set in Analysis Service Configuration."); }
public void TimeSeriesUpdatesTest() { // Construct a unique PI Point name string pointNameFormat = $"TimeSeriesUpdateTestPoint{AFTime.Now}"; bool signupCompleted = false; using (var myDataPipe = new PIDataPipe(AFDataPipeType.TimeSeries)) { Output.WriteLine($"Create a PI Point on [{Settings.PIDataArchive}] with compression off."); var points = Fixture.CreatePIPoints(pointNameFormat, 1, true); try { Output.WriteLine($"Sign up for time-series updates on PI Point [{pointNameFormat}]."); myDataPipe.AddSignups(points.ToList()); signupCompleted = true; var startTime = AFTime.Now.ToPIPrecision() + TimeSpan.FromDays(-1); int eventCount = 1000; int totalCount = 0; // Send events to each PI Point, the event's value is calculated from the timestamp Output.WriteLine($"Write {eventCount} events to the new PI Point."); Fixture.SendTimeBasedPIEvents(startTime, eventCount, points.ToList()); // Checks if Update Events are retrieved a few times Output.WriteLine($"Get the update events."); var eventsRetrieved = new AFListResults <PIPoint, AFDataPipeEvent>(); AssertEventually.True(() => { eventsRetrieved = myDataPipe.GetUpdateEvents(eventCount); totalCount += eventsRetrieved.Count(); return(totalCount == eventCount); }, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(1), $"Failed to retrieve {eventCount} update events, retrieved {totalCount} instead."); Output.WriteLine("Retrieved update events successfully."); } finally { if (signupCompleted) { myDataPipe.RemoveSignups(points.ToList()); } Output.WriteLine("Delete all newly created PI Points."); Fixture.DeletePIPoints(pointNameFormat, Output); } } }
public void ChannelsTest() { var testStart = DateTime.UtcNow; // Get Data Archive object from PI Web API to extract its WebId var dataArchiveUrl = $"{Fixture.HomePageUrl}/dataservers?path=\\PIServers[{Settings.PIDataArchive}]"; Output.WriteLine($"Get Data Archive data through Web API using Url [{dataArchiveUrl}]."); var dataArchiveData = JObject.Parse(Fixture.Client.DownloadString(dataArchiveUrl)); // Verifies test PI Point is found var piPointUrl = $"{Fixture.HomePageUrl}/dataservers/{(string)dataArchiveData["WebId"]}/points?nameFilter={PIPointName}"; Output.WriteLine($"Get PI Point data for [{PIPointName}] through Web API using Url [{piPointUrl}]."); var piPointData = JObject.Parse(Fixture.Client.DownloadString(piPointUrl)); Assert.True(piPointData["Items"].Count() > 0, $"Could not find test PI Point [{PIPointName}]."); var webId = piPointData["Items"][0]["WebId"].ToString(); Output.WriteLine($"Open channel to a stream for PI Point data for [{PIPointName}]."); var waitTimeInSeconds = 60; var pollIntervalInSeconds = 5; AssertEventually.True( () => { using (var cancellationSource = new CancellationTokenSource()) { var runTask = ReadChannelData(webId, cancellationSource.Token); var timeOutSeconds = waitTimeInSeconds; var taskCompleted = runTask.Wait(TimeSpan.FromSeconds(timeOutSeconds)); Assert.True(taskCompleted, $"The channel for [{PIPointName}] did not return data from its stream in the allotted time frame ({timeOutSeconds} seconds)."); } Assert.True(_channelMessage != null, $"The channel for [{PIPointName}] did not return data from its stream."); var updateEvent = JObject.Parse(_channelMessage); var timeStamp = (DateTime)updateEvent["Items"][0]["Items"][0]["Timestamp"]; return(timeStamp > testStart); }, TimeSpan.FromSeconds(waitTimeInSeconds), TimeSpan.FromSeconds(pollIntervalInSeconds), $"Test failed to retrieve a channel event with a timestamp after test start time [{testStart}] within {waitTimeInSeconds} seconds. " + $"This may indicate that the data ingress for {PIPointName} to PI Data Archive was delayed, or a longer CalculationWaitTimeInSeconds " + $"has been set in Analysis Service Configuration."); }
public void PIPointsTest() { PIServer piServer = PIFixture.PIServer; int count = 10; var pointPrefix = "PIPointsTest_Point"; try { // Create PI Point and verify Output.WriteLine($"Creating PI Points with prefix [{pointPrefix}] with default attributes and verifying."); var points = PIFixture.CreatePIPoints($"{pointPrefix}#", count); var returnedPoints = PIPoint.FindPIPoints(piServer, $"{pointPrefix}*"); Assert.True(returnedPoints.Count() == count, $"Expected to find {count} PI Points on Data Archive [{piServer}], actually found {returnedPoints.Count()}."); var timestamp = new AFTime("*-10m"); // Set Value of PI Points Output.WriteLine("Updating PI Points with new values."); for (int i = 0; i < returnedPoints.Count(); i++) { returnedPoints.ElementAt(i).UpdateValue(new AFValue(i, timestamp), AFUpdateOption.NoReplace); } // Check for updated values Output.WriteLine("Checking PI Points were updated with new values."); for (int i = 0; i < count; i++) { AssertEventually.Equals(returnedPoints.ElementAt(i).CurrentValue(), new AFValue(Convert.ToSingle(i), timestamp.ToPIPrecision())); } // Delete PI Points and verify Output.WriteLine("Deleting PI Points that were created and verifying."); PIFixture.DeletePIPoints($"{pointPrefix}*", Output); returnedPoints = PIPoint.FindPIPoints(piServer, $"{pointPrefix}*"); Assert.True(returnedPoints.Count() == 0, $"Expected to find no PI Points with prefix [{pointPrefix}], but {returnedPoints.Count()} were found."); } finally { PIFixture.DeletePIPoints($"{pointPrefix}*", Output); } }
public void WindowsIdMappingTest() { Utils.CheckTimeDrift(Fixture, Output); // Disconnect from the PISERVER Output.WriteLine($"Disconnect from PI Server [{Fixture.PIServer}]."); Fixture.PIServer.Disconnect(); AFTime startTime = AFTime.Now.ToPIPrecision(); string startTimePI = PIDAUtilities.ToPiTimeString(startTime.LocalTime); // Connect again to check for the logs for identity used to get into PISERVER Output.WriteLine($"Reconnect to PI Server [{Fixture.PIServer}]."); Fixture.PIServer.Connect(); // window of time to check for logged messages AFTime endTime = startTime + TimeSpan.FromMinutes(5); string endTimePI = PIDAUtilities.ToPiTimeString(endTime.LocalTime); int expectedMsgID = 7082; Output.WriteLine($"Check if {PIFixture.RequiredPIIdentity} is one of the user identities."); AssertEventually.True(() => { // The test server is expected to have a mapping for the user running the tests mapped to piadmins. // check piadmins identity is in the list // Then we check if the Windows Login method is used IList <PIIdentity> myCurrentList = Fixture.PIServer.CurrentUserIdentities; myCurrentList.Single(x => x.Name.Equals(PIFixture.RequiredPIIdentity, StringComparison.OrdinalIgnoreCase)); // Checks for windows login five times return(PIDAUtilities.FindMessagesInLog(Fixture, startTimePI, endTimePI, expectedMsgID, "*Method: Windows Login*")); }, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(3), "Windows login not found."); }
public void CheckPIPointWritePermissionTest() { using (var piFixture = new PIFixture()) { // Find the target a PI Point string manualInputPoint = @"OSIsoftTests.Region 1.Manual Input"; Output.WriteLine($"Search for PI Point [{manualInputPoint}]."); var point = PIPoint.FindPIPoint(piFixture.PIServer, manualInputPoint); // Prepare the event to be written var eventToWrite = new AFValue((float)Math.PI, (AFTime.Now + TimeSpan.FromSeconds(1)).ToPIPrecision()); // Send the event to be written Output.WriteLine($"Write an event to PI Point [{manualInputPoint}]."); point.UpdateValue(eventToWrite, AFUpdateOption.InsertNoCompression); // Read the current value to verify that the event was written successfully Output.WriteLine($"Verify the event has been sent to PI Point [{manualInputPoint}]."); AssertEventually.True( () => eventToWrite.Equals(point.CurrentValue()), $"Failed to send data to PI Point [{manualInputPoint}] on {piFixture.PIServer.Name}. Please check if the running user has write access to PI Data Archive. " + $"If buffering is configured, make sure PI Buffer Subsystem connects to PI Data Archive with appropriate PI mappings."); } }
public void NotificationRuleSendEmailAnnotationTest() { AFDatabase db = AFFixture.AFDatabase; var elementName = $"{NotificationsFixture.TestPrefix}_{NotificationsFixture.TestInfix}_{nameof(NotificationRuleSendEmailAnnotationTest)}"; var notificationRuleName = $"{NotificationsFixture.TestPrefix}_{NotificationsFixture.TestInfix}_NotificationRule1"; var eventFrameName = $"{NotificationsFixture.TestPrefix}_{NotificationsFixture.TestInfix}_EventFrame1"; AFFixture.RemoveElementIfExists(elementName, Output); Guid?eventFrameId = null; AFNotificationContactTemplate emailEndpoint = null; try { emailEndpoint = CreateEmailEndpoint(nameof(NotificationRuleSendEmailAnnotationTest)); Output.WriteLine($"Create email notification contact template [{emailEndpoint.Name}]."); PISystem.CheckIn(); Output.WriteLine($"Create element [{elementName}] with notification rule [{notificationRuleName}]"); var element = db.Elements.Add(elementName); var notificationRule = element.NotificationRules.Add(notificationRuleName); notificationRule.Criteria = $"Name:{NotificationsFixture.TestPrefix}*"; var format = notificationRule.DeliveryFormats.Add("testFormat", EmailPlugIn); NotificationsFixture.SetFormatProperties(format.Properties, nameof(NotificationRuleSendEmailAnnotationTest)); var subscriber = notificationRule.Subscribers.Add(emailEndpoint); subscriber.DeliveryFormat = format; notificationRule.SetStatus(AFStatus.Enabled); db.CheckIn(); Output.WriteLine("Waiting for notification to startup."); Thread.Sleep(TimeSpan.FromSeconds(10)); var eventFrame = new AFEventFrame(db, eventFrameName) { PrimaryReferencedElement = element, }; eventFrame.SetStartTime(AFTime.Now); eventFrame.CheckIn(); eventFrameId = eventFrame.ID; Output.WriteLine($"Created event frame [{eventFrameName}]."); // Verify annotations are gotten correctly var annotations = eventFrame.GetAnnotations(); if (annotations.Count == 0) { AssertEventually.True( () => eventFrame.GetAnnotations().Count != 0, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(5), "Did not find any annotations."); annotations = eventFrame.GetAnnotations(); } Output.WriteLine("Verify the notification is sent for the event frame and the annotation is set properly."); Assert.True(annotations.Count == 1, $"Expected to get only one annotation, but got {annotations.Count}."); Assert.True(annotations[0].Owner.ID == eventFrameId, "The owner of the annotation is not set properly."); Assert.True(annotations[0].Name == NotificationsFixture.AnnotationName, "The name of the annotation is not set properly."); Assert.False(string.IsNullOrWhiteSpace(annotations[0].Description), "The description of the annotation is not set properly."); Assert.True((string)annotations[0].Value == string.Format(CultureInfo.InvariantCulture, NotificationsFixture.SentAnnotation, 1), "The value of the annotation is not set properly."); Output.WriteLine("Verify the content of the annotation is set properly."); Assert.False(string.IsNullOrWhiteSpace(annotations[0].Description), "The description of the annotation is not set properly."); var description = NotificationsFixture.DeserializeAnnotationDescription(annotations[0].Description); var subscribers = description.Subscribers; Assert.True(description.Notification == notificationRuleName, "The notification rule name is not set properly."); Assert.True(subscribers.Count == 1, $"Expected to get only one subscriber, but got {description.Subscribers.Count}."); Assert.True(subscribers[0].Name == emailEndpoint.Name, "The name of the subscriber is not set properly."); Assert.True(subscribers[0].Configuration == Settings.PINotificationsRecipientEmailAddress, "The email address of the subscriber is not set properly."); Assert.True(subscribers[0].Type == "Email", "The type of the subscriber is not set properly."); } finally { AFFixture.RemoveElementIfExists(elementName, Output); if (eventFrameId != null) { AFFixture.RemoveEventFrameIfExists(eventFrameId.GetValueOrDefault(), Output); } if (emailEndpoint != null) { PISystem.NotificationContactTemplates.Remove(emailEndpoint.ID); PISystem.CheckIn(); } } }
public void NotificationRuleSendToEscalationContactTest() { AFDatabase db = AFFixture.AFDatabase; var elementName = $"{NotificationsFixture.TestPrefix}_{NotificationsFixture.TestInfix}_{nameof(NotificationRuleSendToEscalationContactTest)}"; var notificationRuleName = $"{NotificationsFixture.TestPrefix}_{NotificationsFixture.TestInfix}_NotificationRule1"; var escalationNotificationContactTemplateName = $"{NotificationsFixture.TestPrefix}_{NotificationsFixture.TestInfix}_Escalation1"; var eventFrameName = $"{NotificationsFixture.TestPrefix}_{NotificationsFixture.TestInfix}_EventFrame1"; var emailContactsCountInEscalation = 2; var escalationPeriod = TimeSpan.FromSeconds(20); AFFixture.RemoveElementIfExists(elementName, Output); Guid?eventFrameId = null; var emailEndpoints = new List <AFNotificationContactTemplate>(); AFNotificationContactTemplate escalation = null; try { Output.WriteLine($"Created group notification contact template [{escalationNotificationContactTemplateName}]" + $" with [{emailContactsCountInEscalation}] email notification contact added."); escalation = new AFNotificationContactTemplate(PISystem, escalationNotificationContactTemplateName) { ContactType = AFNotificationContactType.Escalation, EscalationTimeout = escalationPeriod, }; escalation.CheckIn(); for (var i = 0; i < emailContactsCountInEscalation; i++) { var emailEndpoint = CreateEmailEndpoint($"{nameof(NotificationRuleSendToEscalationContactTest)}_{i}"); escalation.NotificationContactTemplates.Add(emailEndpoint); emailEndpoints.Add(emailEndpoint); } PISystem.CheckIn(); Output.WriteLine($"Created element [{elementName}] with notification rule [{notificationRuleName}]."); var element = db.Elements.Add(elementName); var notificationRule = element.NotificationRules.Add(notificationRuleName); notificationRule.Criteria = $"Name:{NotificationsFixture.TestPrefix}*"; var subscriber = notificationRule.Subscribers.Add(escalation); notificationRule.SetStatus(AFStatus.Enabled); db.CheckIn(); Output.WriteLine("Waiting for notification to startup."); Thread.Sleep(TimeSpan.FromSeconds(10)); var eventFrame = new AFEventFrame(db, eventFrameName) { PrimaryReferencedElement = element, }; Output.WriteLine($"Create event frame [{eventFrameName}]."); eventFrame.SetStartTime(AFTime.Now); eventFrame.CheckIn(); eventFrameId = eventFrame.ID; Output.WriteLine("Waiting for escalation period."); Thread.Sleep(TimeSpan.FromSeconds(30)); // Verify annotations are gotten correctly var annotations = eventFrame.GetAnnotations(); if (annotations.Count == 0) { AssertEventually.True( () => eventFrame.GetAnnotations().Count != 0, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(5), "Did not find any annotations."); annotations = eventFrame.GetAnnotations(); } Output.WriteLine("Verify the notification is sent for the event frame and the annotation is set properly."); Assert.True(annotations.Count == emailContactsCountInEscalation, $"Expected to get [{emailContactsCountInEscalation}] annotations, but got [{annotations.Count}]."); for (var i = 0; i < emailContactsCountInEscalation; i++) { Assert.True(annotations[i].Name == NotificationsFixture.AnnotationName, "The name of the annotation is not set properly."); Assert.False(string.IsNullOrWhiteSpace(annotations[i].Description), "The description of the annotation is not set properly."); var description = NotificationsFixture.DeserializeAnnotationDescription(annotations[i].Description); var subscribers = description.Subscribers; Assert.True(description.Notification == notificationRuleName, "The notification rule name is not set properly."); Assert.True(subscribers.Count == 1, $"Expected to get only one subscriber, but got {description.Subscribers.Count}."); Assert.True(subscribers[0].Name == emailEndpoints[i].Name, $"The name of the [{i}] subscriber is not set properly."); Assert.True(subscribers[0].Configuration == Settings.PINotificationsRecipientEmailAddress, $"The configuration of the [{i}] subscriber is not displayed in the annotation."); Assert.True(subscribers[0].Type == "Email", $"The type of the [{i}] subscriber is not set properly."); if (i == 0) { Assert.True((string)annotations[i].Value == string.Format(CultureInfo.InvariantCulture, NotificationsFixture.SentAnnotation, 1), "The value of the annotation is not set properly."); } else { Assert.True((string)annotations[i].Value == string.Format(CultureInfo.InvariantCulture, NotificationsFixture.EscalatedAnnotation, 1), "The value of the annotation is not set properly."); } } for (var i = emailContactsCountInEscalation - 1; i > 0; i--) { Assert.True(annotations[i].CreationDate - annotations[i - 1].CreationDate >= escalationPeriod, $"The escalation period is not performed properly."); } } finally { AFFixture.RemoveElementIfExists(elementName, Output); if (eventFrameId != null) { AFFixture.RemoveEventFrameIfExists(eventFrameId.GetValueOrDefault(), Output); } if (escalation != null) { PISystem.NotificationContactTemplates.Remove(escalation.ID); } foreach (var emailEndpoint in emailEndpoints) { PISystem.NotificationContactTemplates.Remove(emailEndpoint.ID); } PISystem.CheckIn(); } }
public void PIDataPipeTimeSeriesTest(PIPointType piPointType, object[] eventValues) { Contract.Requires(eventValues != null); const string PointName = "PIDataPipeTests_PIPoint"; AFDatabase db = AFFixture.AFDatabase; PIServer piServer = PIFixture.PIServer; var piDataPipe = new PIDataPipe(AFDataPipeType.TimeSeries); var piPointList = new PIPointList(); var now = AFTime.NowInWholeSeconds; try { Output.WriteLine("Create the Future PI Points with Zero Compression and specified PI Point type."); PIFixture.DeletePIPoints(PointName + "*", Output); var testPIPoints = PIFixture.CreatePIPoints(PointName + "###", eventValues.Length, new Dictionary <string, object> { { PICommonPointAttributes.PointType, piPointType }, { PICommonPointAttributes.ExceptionDeviation, 0 }, { PICommonPointAttributes.ExceptionMaximum, 0 }, { PICommonPointAttributes.Compressing, 0 }, { PICommonPointAttributes.DigitalSetName, "Phases" }, { PICommonPointAttributes.Future, true }, }); Assert.True(testPIPoints.Count() == eventValues.Length, $"Unable to create all the test PI Points."); piPointList.AddRange(testPIPoints); // Add the PI Point as sign up to the PIDataPipe. Output.WriteLine($"Sign up all PI Points with PIDataPipe."); var afErrors = piDataPipe.AddSignups(piPointList); var prefixErrorMessage = "Adding sign ups to the PIDataPipe was unsuccessful."; Assert.True(afErrors == null, userMessage: afErrors?.Errors.Aggregate(prefixErrorMessage, (msg, error) => msg += $" PI Point: [{error.Key.Name}] Error: [{error.Value.Message}] ")); // Write one data value to each PI Point. var expectedAFValues = new AFValues(); for (int i = 0; i < eventValues.Length; i++) { AFValue afValue = null; var timestamp = now + TimeSpan.FromMinutes(i - eventValues.Length); // Special Handling of Input Data for Digital and Timestamp switch (piPointType) { case PIPointType.Digital: afValue = new AFValue(new AFEnumerationValue("Phases", (int)eventValues[i]), timestamp); break; case PIPointType.Timestamp: afValue = new AFValue(new AFTime(eventValues[i], now), timestamp); break; default: afValue = new AFValue(eventValues[i], timestamp); break; } Output.WriteLine($"Writing Value [{eventValues[i]}] with Timestamp [{timestamp}] to PI Point [{piPointList[i].Name}]."); piPointList[i].UpdateValue(afValue, AFUpdateOption.InsertNoCompression); // If writing digital states, we need to save the corresponding value for verification. // Since we are using Phases, 0 ~ Phase1, 1 ~ Phase2, etc. if (piPointType == PIPointType.Digital) { int input = (int)eventValues[i]; afValue = new AFValue(new AFEnumerationValue($"Phase{input + 1}", input), timestamp); } afValue.PIPoint = piPointList[i]; expectedAFValues.Add(afValue); } // Retry assert to retrieve expected Update Events from the PIDataPipe var actualAFValues = new AFValues(); Output.WriteLine($"Reading Events from the PI DataPipe."); AssertEventually.True(() => { var updateEvents = piDataPipe.GetUpdateEvents(eventValues.Length); prefixErrorMessage = "Retrieving Update Events from the PIDataPipe was unsuccessful."; Assert.False(updateEvents.HasErrors, userMessage: updateEvents.Errors?.Aggregate(prefixErrorMessage, (msg, error) => msg += $" PI Point: [{error.Key.Name}] Error: [{error.Value.Message}] ")); actualAFValues.AddRange(updateEvents.Results.Select(update => update.Value)); if (actualAFValues.Count >= expectedAFValues.Count) { // Verify that all expected update events are received from the PIDataPipe Assert.True(expectedAFValues.Count == actualAFValues.Count, "PIDataPipe returned more events than expected. " + $"Expected Count: {expectedAFValues.Count}, Actual Count: {actualAFValues.Count}."); return(true); } return(false); }, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(0.5), "Unable to retrieve events within the time frame."); // Verify all received events. Output.WriteLine($"Verifying all {actualAFValues.Count} events from the PI DataPipe."); for (int i = 0; i < actualAFValues.Count; i++) { // Special handling of Output events for Timestamp if (piPointType == PIPointType.Timestamp) { actualAFValues[i].Value = new AFTime(actualAFValues[i].Value, now); } AFFixture.CheckAFValue(actualAFValues[i], expectedAFValues[i]); Assert.True(object.Equals(actualAFValues[i].PIPoint, expectedAFValues[i].PIPoint), $"Unexpected PI Point Association. Expected: [{expectedAFValues[i].PIPoint}], Actual: [{actualAFValues[i].PIPoint}]."); } // Remove all sign ups from the PIDataPipe Output.WriteLine($"Remove all PI Point sign ups from PIDataPipe."); afErrors = piDataPipe.RemoveSignups(piPointList); prefixErrorMessage = "Removing sign ups to the PIDataPipe was unsuccessful."; Assert.True(afErrors == null, userMessage: afErrors?.Errors.Aggregate(prefixErrorMessage, (msg, error) => msg += $" PI Point: [{error.Key.Name}] Error: [{error.Value.Message}] ")); // Write dummy values to the PI Points and confirm PI DataPipe receives none. Output.WriteLine($"Write dummy values to the PI Points."); for (int i = 0; i < eventValues.Length; i++) { piPointList[i].UpdateValue(new AFValue(eventValues[i], now), AFUpdateOption.InsertNoCompression); } Output.WriteLine($"Verify no events are received by the PIDataPipe."); var noEvents = piDataPipe.GetUpdateEvents(eventValues.Length); prefixErrorMessage = "Retrieving Update Events from the PIDataPipe was unsuccessful."; Assert.False(noEvents.HasErrors, userMessage: noEvents.Errors?.Aggregate(prefixErrorMessage, (msg, error) => msg += $" PI Point: [{error.Key.Name}] Error: [{error.Value.Message}] ")); Assert.True(noEvents.Count == 0, "PIDataPipe received events even after removing all sign ups."); } finally { piDataPipe.RemoveSignups(piPointList); piDataPipe.Dispose(); PIFixture.DeletePIPoints(PointName + "*", Output); } }
public void CreatePointSendEventsAndVerify() { string pointName = $"CreatePointSendEventsAndVerify{AFTime.Now}"; IDictionary<string, object> attributes = new Dictionary<string, object>() { { PICommonPointAttributes.Tag, pointName }, { PICommonPointAttributes.PointType, PIPointType.Int32 }, { PICommonPointAttributes.Compressing, 0 }, }; // Create a PI Point Output.WriteLine($"Create PI Point [{pointName}]."); PIPoint point = Fixture.PIServer.CreatePIPoint(pointName, attributes); // Assert that the PI Point creation was successful Assert.True(PIPoint.FindPIPoint(Fixture.PIServer, pointName) != null, $"Could not find PI Point [{pointName}] on Data Archive [{Fixture.PIServer.Name}]."); try { // Prepare the events to be written var eventsToWrite = new AFValues(); var start = AFTime.Now.ToPIPrecision(); int eventsCount = 10; var randomData = new byte[eventsCount]; using (var random = RandomNumberGenerator.Create()) { random.GetBytes(randomData); } for (int i = 0; i < eventsCount; i++) { var evnt = new AFValue(Convert.ToInt32(randomData[i]), start + TimeSpan.FromSeconds(i)); eventsToWrite.Add(evnt); } // Send the events to be written Output.WriteLine($"Write events to PI Point [{pointName}]."); point.UpdateValues(eventsToWrite, AFUpdateOption.InsertNoCompression); // Read the events to verify that it was written successfully var eventsRead = new AFValues(); Output.WriteLine($"Read events from PI Point [{pointName}]."); AssertEventually.Equal( eventsToWrite.Count, () => point.RecordedValuesByCount(start, eventsCount, true, AFBoundaryType.Inside, null, false).Count, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(0.2)); eventsRead = point.RecordedValuesByCount(start, eventsCount, true, AFBoundaryType.Inside, null, false); for (int j = 0; j < eventsCount; j++) { Assert.True(eventsToWrite[j].Value.Equals(eventsRead[j].Value), $"Expected the value of the written event {AFFixture.DisplayAFValue(eventsToWrite[j])} " + $"and the read event {AFFixture.DisplayAFValue(eventsRead[j])} to be equal."); } } finally { // Delete the PI Point to cleanup Fixture.DeletePIPoints(pointName, Output); } }
public void UpdateEventValuesTest() { string pointName = $"UpdateEventValuesTest{AFTime.Now}"; IDictionary<string, object> attributes = new Dictionary<string, object>() { { PICommonPointAttributes.Tag, pointName }, { PICommonPointAttributes.PointType, PIPointType.Int32 }, { PICommonPointAttributes.Compressing, 0 }, }; // Create a PI Point Output.WriteLine($"Create PI Point [{pointName}]."); PIPoint point = Fixture.PIServer.CreatePIPoint(pointName, attributes); // Assert that the PI Point creation was successful Assert.True(PIPoint.FindPIPoint(Fixture.PIServer, pointName) != null, $"Could not find PI Point [{pointName}] on Data Archive [{Fixture.PIServer.Name}]."); try { // Prepare the events to be written var eventsToWrite = new AFValues(); var start = AFTime.Now.ToPIPrecision(); int eventsCount = 10; var randomData = new byte[eventsCount]; var valuesToWrite = new List<int>(); var timeStamps = new List<AFTime>(); using (var random = RandomNumberGenerator.Create()) { random.GetBytes(randomData); for (int i = 0; i < eventsCount; i++) { int value = Convert.ToInt32(randomData[i]); var timestamp = start + TimeSpan.FromMinutes(i); var evnt = new AFValue(value, timestamp); eventsToWrite.Add(evnt); valuesToWrite.Add(value); timeStamps.Add(timestamp); } } // Send the events to be written Output.WriteLine($"Write {eventsCount} events to PI Point [{pointName}]."); point.UpdateValues(eventsToWrite, AFUpdateOption.InsertNoCompression); Thread.Sleep(TimeSpan.FromSeconds(1)); // Read the events to verify that it was written successfully var eventsRead = new AFValues(); Output.WriteLine($"Read events from point [{pointName}]."); AssertEventually.True(() => { eventsRead = point.RecordedValuesByCount(start, eventsCount, true, AFBoundaryType.Inside, null, false); if (eventsToWrite.Count != eventsRead.Count) { Output.WriteLine($"The read event count {eventsRead.Count} does not match the written event count {eventsToWrite.Count}."); return false; } for (int j = 0; j < eventsCount; j++) { if (!eventsToWrite[j].Value.Equals(eventsRead[j].Value)) { Output.WriteLine($"Written event value {AFFixture.DisplayAFValue(eventsToWrite[j])} " + $"did not match read event value {AFFixture.DisplayAFValue(eventsRead[j])}."); return false; } } return true; }, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(5), $"The events read back do not match the events written on the PI Data Archive [{Fixture.PIServer.Name}]."); // Update/edit the values and send again var updatedNewValues = new List<int>(); var eventsUpdated = new AFValues(); randomData = new byte[eventsCount]; using (var random = RandomNumberGenerator.Create()) { random.GetBytes(randomData); for (int i = 0; i < eventsCount; i++) { // Ensure that the updated values are different than the written values. int value = Convert.ToInt32(randomData[i]) + 256; var evnt = new AFValue(value, timeStamps[i]); eventsUpdated.Add(evnt); updatedNewValues.Add(value); } } // Send the updated events to be written Output.WriteLine($"Write updated events to PI Point [{pointName}]."); point.UpdateValues(eventsUpdated, AFUpdateOption.Replace); // Read the events to verify that it was updated successfully eventsRead = new AFValues(); Output.WriteLine($"Read events from PI Point [{pointName}]."); AssertEventually.True(() => { eventsRead = point.RecordedValuesByCount(start, eventsCount, true, AFBoundaryType.Inside, null, false); if (eventsUpdated.Count != eventsRead.Count) { Output.WriteLine($"The read event count {eventsRead.Count} does not match the updated event count {eventsUpdated.Count}."); return false; } for (int j = 0; j < eventsCount; j++) { if (!eventsUpdated[j].Value.Equals(eventsRead[j].Value)) { Output.WriteLine($"Updated event value {AFFixture.DisplayAFValue(eventsUpdated[j])} " + $"did not match read event value {AFFixture.DisplayAFValue(eventsRead[j])}."); return false; } if (eventsToWrite[j].Value.Equals(eventsRead[j].Value)) { Output.WriteLine($"Written event value {AFFixture.DisplayAFValue(eventsToWrite[j])} " + $"did match read event value {AFFixture.DisplayAFValue(eventsRead[j])}. The values should not be equal."); return false; } } return true; }, $"The events read back do not match the events written or updated on the PI Data Archive [{Fixture.PIServer.Name}]."); } finally { // Delete the PI Point to cleanup Fixture.DeletePIPoints(pointName, Output); } }
public void DeleteValuesTest() { string pointName = $"DeleteValuesTest{AFTime.Now}"; IDictionary<string, object> attributes = new Dictionary<string, object>() { { PICommonPointAttributes.Tag, pointName }, { PICommonPointAttributes.PointType, PIPointType.Int32 }, { PICommonPointAttributes.Compressing, 0 }, }; // Create a PI Point Output.WriteLine($"Create PI Point [{pointName}]."); PIPoint point = Fixture.PIServer.CreatePIPoint(pointName, attributes); // Assert that the PI Point creation was successful Assert.True(PIPoint.FindPIPoint(Fixture.PIServer, pointName) != null, $"Could not find PI Point [{pointName}] on Data Archive [{Fixture.PIServer.Name}]."); try { // Prepare the events to be written var eventsToWrite = new AFValues(); var start = AFTime.Now.ToPIPrecision(); int eventsCount = 10; var randomData = new byte[eventsCount]; using (var random = RandomNumberGenerator.Create()) { random.GetBytes(randomData); for (int i = 0; i < eventsCount; i++) { var evnt = new AFValue(Convert.ToInt32(randomData[i]), start + TimeSpan.FromSeconds(i)); eventsToWrite.Add(evnt); } } // Send the events to be written Output.WriteLine($"Write events to PI Point [{pointName}]."); point.UpdateValues(eventsToWrite, AFUpdateOption.InsertNoCompression); // Read the events to verify that the events write was successful var eventsRead = new AFValues(); Output.WriteLine($"Read events from PI Point [{pointName}]."); AssertEventually.True(() => { eventsRead = point.RecordedValuesByCount(start, eventsCount, true, AFBoundaryType.Inside, null, false); if (eventsToWrite.Count != eventsRead.Count) { Output.WriteLine($"The read event count {eventsRead.Count} does not match the written event count {eventsToWrite.Count}."); return false; } else { for (int j = 0; j < eventsCount; j++) { if (!eventsToWrite[j].Value.Equals(eventsRead[j].Value)) { Output.WriteLine($"Written event value {AFFixture.DisplayAFValue(eventsToWrite[j])} " + $"did not match read event value {AFFixture.DisplayAFValue(eventsRead[j])}."); return false; } } } return true; }, $"The events read back do not match the events written to PI Data Archive [{Fixture.PIServer.Name}]."); // Delete the events Output.WriteLine($"Delete events from PI Point [{pointName}]."); eventsRead.Clear(); point.UpdateValues(eventsToWrite, AFUpdateOption.Remove); AssertEventually.True(() => { eventsRead = point.RecordedValuesByCount(start, eventsCount, true, AFBoundaryType.Inside, null, false); return eventsRead.Count == 0; }, $"The return event count should be 0 after deleting the events, but it was actually {eventsRead.Count}."); } finally { // Delete the PI Point to cleanup Fixture.DeletePIPoints(pointName, Output); } }