public CacheItemPriorityQueueTestItem (string serialized) { if (String.IsNullOrEmpty (serialized)) throw new ArgumentException ("serialized"); string[] parts = serialized.Split (';'); if (parts.Length != 10) throw new InvalidOperationException ("Invalid serialized data."); ListIndex = Int32.Parse (parts [0]); QueueCount = Int32.Parse (parts [1]); int i = Int32.Parse (parts [2]); if (i < (int)QueueOperation.Enqueue || i > (int)QueueOperation.Update) throw new InvalidOperationException ("Invalid value for Operation in the serialized data."); Operation = (QueueOperation)i; IsDisabled = GetBool (parts [3]); IsNull = GetBool (parts [4]); Disable = GetBool (parts [5]); OperationCount = Int32.Parse (parts [6]); Guid = parts [7]; PriorityQueueIndex = Int32.Parse (parts [8]); ExpiresAt = Int64.Parse (parts [9]); if (Guid.Length == 0) Guid = null; }
public AlgorithmStepData(string title, string description, QueueOperation onDisplay, QueueOperation onOrangeClick = null) { Title = title; Description = description; OnDisplay = onDisplay; OnOrangeClick = onOrangeClick; }
public CacheItemPriorityQueueTestItem(string serialized) { if (String.IsNullOrEmpty(serialized)) { throw new ArgumentException("serialized"); } string[] parts = serialized.Split(';'); if (parts.Length != 8) { throw new InvalidOperationException("Invalid serialized data."); } ListIndex = Int32.Parse(parts [0]); QueueCount = Int32.Parse(parts [1]); int i = Int32.Parse(parts [2]); if (i < (int)QueueOperation.Enqueue || i > (int)QueueOperation.QueueSize) { throw new InvalidOperationException("Invalid value for Operation in the serialized data."); } Operation = (QueueOperation)i; IsDisabled = GetBool(parts [3]); IsNull = GetBool(parts [4]); Disable = GetBool(parts [5]); OperationCount = Int32.Parse(parts [6]); Guid = parts [7]; if (Guid.Length == 0) { Guid = null; } }
public void TestCleanup() { DependencyInjection(DefaultAppSettingValues); QueueOperation.GetMessages(settings.MailQueueName, settings.MailQueueConnectionString); using (SqlConnection connection = new SqlConnection(settings.PrimaryDbConnectionString)) { try { connection.Open(); using (SqlCommand command = new SqlCommand(ClearTableCommand, connection)) { command.ExecuteNonQuery(); } } finally { connection.Close(); } } foreach (CloudBlockBlob blockBlob in failureBlob.Client.GetBlockBlobs(DefaultAppSettingValues["FailureBlobContainerName"])) { blockBlob.DeleteIfExistsAsync().Wait(); } }
public QueueOperation EnqueueSynchronous(Action a) { var operation = new QueueOperation((s) => a(), null, ownerThread, true); actionQueue.Add(operation); return(operation); }
public QueueOperation EnqueueSynchronous(SendOrPostCallback d, object state) { var operation = new QueueOperation(d, state, ownerThread, true); actionQueue.Add(operation); return(operation); }
public void MonitorParentChildConnectTableTest(string no, string in_InitializeSqlSet, string expected_AlarmQueueSet, string expected_LogMessages, string remarks) { List <TestLog> actual_logs = new List <TestLog>(); // DI DependencyInjection(DefaultAppSettingValues, actual_logs); // テストデータ準備 { if (Directory.Exists(in_InitializeSqlSet)) { using (SqlConnection connection = new SqlConnection(settings.PrimaryDbConnectionString)) { try { connection.Open(); foreach (string path in Directory.GetFiles(in_InitializeSqlSet, "*.sql", SearchOption.AllDirectories)) { string cmdText = File.ReadAllText(path); using (SqlCommand command = new SqlCommand(cmdText, connection)) { command.ExecuteNonQuery(); } } } finally { connection.Close(); } } } } // 期待値 List <string> expected_queues = Directory.Exists(expected_AlarmQueueSet) ? Directory.GetFiles(expected_AlarmQueueSet, "*.json").Select(x => File.ReadAllText(x)).ToList() : new List <string>(); List <string> expected_log_messages = (expected_LogMessages != null && File.Exists(expected_LogMessages)) ? File.ReadLines(expected_LogMessages).ToList() : new List <string>(); // テスト実行 target.MonitorParentChildConnectTable(null, new TestLogger <ParentChildrenConnectionMonitorController>(actual_logs)); // テスト結果 List <string> actual_queses = QueueOperation.GetMessages(settings.AlarmQueueName, settings.QueueStorageConnectionString); List <string> actual_log_messages = actual_logs.Select(x => x.GetSimpleText()).ToList(); // 確認 CollectionAssert.AreEqual(expected_queues, actual_queses); foreach (var expected_log_message in expected_log_messages) { var matching_element = actual_log_messages.FirstOrDefault(actual => actual.Contains(expected_log_message)); Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotNull(matching_element, string.Format("「{0}」に一致する要素が見つかりません", expected_log_message)); if (matching_element != null) { actual_log_messages.Remove(matching_element); } } }
/// <summary> /// アラームキューへメッセージを送信する /// </summary> /// <param name="message">送信するメッセージ</param> public void SendMessageToAlarmQueue(string message) { try { _logger.EnterJson("{0}", new { message }); _queuePolly.Execute(() => { QueueOperation.SendMessage(_appSettings.AlarmQueueName, _appSettings.QueueStorageConnectionString, message); }); } catch (Exception e) { throw new RmsException(string.Format("アラームキューへのメッセージ送信に失敗しました。(message = {0})", message), e); } finally { _logger.Leave(); } }
/// <summary> /// 当需要执行操作时调用此方法。 /// </summary> protected override void OnExecute() { using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(mXml))) { var reader = XmlReader.Create(stream); //Declaration reader.Read(); //GameObject reader.Read(); var resultObject = reader.GetGameObject(mContext, true); Result = resultObject; mReferenceOperations = mContext.GetDependencyOperations(DependencyLevel.Reference).ToArray(); mDecorateOperations = mContext.GetDependencyOperations(DependencyLevel.Decorate).ToArray(); mRequiredOperations = mContext.GetDependencyOperations(DependencyLevel.Required).ToArray(); var decorateQueue = new MainThreadOperationQueue(BlazeEngine.Instance); foreach (var operation in mDecorateOperations) { decorateQueue.Enqueue(operation); } var criticalOperations = new List <ILoadOperation>(); criticalOperations.AddRange(mRequiredOperations); criticalOperations.AddRange(mReferenceOperations); var requiredQueue = new MainThreadOperationQueue(BlazeEngine.Instance); var requiredOperations = criticalOperations.Select(op => (IOperation)op); var requiredQueueOperation = new QueueOperation(requiredQueue, requiredOperations); requiredQueueOperation.OnSucceed(() => { mContext.Finish(); resultObject.SetActive(true); base.OnExecute(); }).Execute(); } }
public void ReceiveDirectoryUsageTest(string no, string in_InitializeSqlSet, string in_Message, string expected_AlarmQueueSet, string expected_FailureBlobFileSet, string expected_LogMessages, string remarks) { List <TestLog> actual_logs = new List <TestLog>(); // DI DependencyInjection(DefaultAppSettingValues, actual_logs); // テストデータ準備 { if (Directory.Exists(in_InitializeSqlSet)) { using (SqlConnection connection = new SqlConnection(settings.PrimaryDbConnectionString)) { try { connection.Open(); foreach (string path in Directory.GetFiles(in_InitializeSqlSet, "*.sql", SearchOption.AllDirectories)) { string cmdText = File.ReadAllText(path); using (SqlCommand command = new SqlCommand(cmdText, connection)) { command.ExecuteNonQuery(); } } } finally { connection.Close(); } } } in_Message = (in_Message != null && File.Exists(in_Message)) ? File.ReadAllText(in_Message) : in_Message; } // 期待値 List <string> expected_queues = Directory.Exists(expected_AlarmQueueSet) ? Directory.GetFiles(expected_AlarmQueueSet, "*.json").Select(x => File.ReadAllText(x)).ToList() : new List <string>(); DirectoryInfo expectedFailureDir = new DirectoryInfo(expected_FailureBlobFileSet); string[] expectedFailureFiles = expectedFailureDir.Exists ? expectedFailureDir.GetFiles("*", SearchOption.AllDirectories).Select(x => x.FullName).OrderBy(x => x).ToArray() : new string[] { }; string[] expected_failure_names = expectedFailureFiles.Select(x => x.Replace(expectedFailureDir.FullName, string.Empty)).ToArray(); string[] expected_failure_contents = expectedFailureFiles.Select(x => File.ReadAllText(x)).ToArray(); List <string> expected_log_messages = (expected_LogMessages != null && File.Exists(expected_LogMessages)) ? File.ReadLines(expected_LogMessages).ToList() : new List <string>(); // テスト実行 target.ReceiveDirectoryUsage(in_Message, new TestLogger <DirectoryUsageMonitorController>(actual_logs)); // テスト結果 List <string> actual_queses = QueueOperation.GetMessages(settings.AlarmQueueName, settings.QueueStorageConnectionString); DirectoryInfo actualDir = new DirectoryInfo(Path.Combine(TestResultRootDir, no)); string[] actualFailureFiles = failureBlob.Client.GetFiles(settings.FailureBlobContainerName, actualDir).OrderBy(x => x).ToArray(); string[] actual_failure_names = actualFailureFiles.Select(x => x.Replace(actualDir.FullName, string.Empty)).ToArray(); string[] actual_failure_contents = actualFailureFiles.Select(x => File.ReadAllText(x)).ToArray(); List <string> actual_log_messages = actual_logs.Select(x => x.GetSimpleText()).ToList(); // 確認 CollectionAssert.AreEqual(expected_queues, actual_queses); CollectionAssert.AreEqual(expected_failure_names, actual_failure_names); CollectionAssert.AreEqual(expected_failure_contents, actual_failure_contents); foreach (var expected_log_message in expected_log_messages) { var matching_element = actual_log_messages.FirstOrDefault(actual => actual.Contains(expected_log_message)); Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotNull(matching_element, string.Format("「{0}」に一致する要素が見つかりません", expected_log_message)); if (matching_element != null) { actual_log_messages.Remove(matching_element); } } }
public void Enqueue(SendOrPostCallback d, object state) { var operation = new QueueOperation(d, state, ownerThread, false); actionQueue.Add(operation); }
public void Enqueue(Action a) { var operation = new QueueOperation((s) => a(), null, ownerThread, false); actionQueue.Add(operation); }
public MSMQFacoty() { queueOperation = new QueueOperation(); }
private void F_LoadCompleted(object sender, FrameLoadCompleteEventArgs e) { log.Debug($"++ Enter F_LoadCompleted from {e.Message}."); // 20200509 因為沒有先 -= F_LoadComplted, 造成了幽靈, 因此一定要 -= F_LoadComplted 在任何Exit之前. // 每次作業F_LoadCompleted只會被呼叫一次,沒有被洗掉的情形 fm.FrameLoadComplete -= F_LoadCompleted; log.Debug($"@@ delete delegate F_LoadCompleted."); // 使用DocumentLoadCompletedButNotFrame, 會造成偶而不動作的症狀, 要找別的方式來處理沒插健保卡的判別 // 方法 if (e.Message == FrameLoadStates.DocumentLoadCompletedButNotFrame) { // 沒有lbluserID, 例如沒插健保卡 // activate hotkeys 1 Activate_Hotkeys(); log.Debug($"++ Exit F_LoadCompleted (1/5). No NHI card inserted."); log.Info("==========================================================================="); log.Info($" "); return; } /// 會有兩次 /// 第一次讀完檔案會再執行javascript, 在local用來認證健保卡, 沒過就不會有第二次 /// 如果認證OK, 會再透過javascript下載個案雲端資料, 觸發第二次 /// 這段程式的目的: /// 1. 取得身分證字號 /// 2. 讀取有哪些tab // 20210719: mark this line to simplify logging // log.Info($"Entered F_LoadCompleted"); HTMLDocument d = (HTMLDocument)g.Document; // 確定身分證字號 string strUID = MakeSure_UID(d.getElementById("ContentPlaceHolder1_lbluserID").innerText); // if (strUID = string.Empty) 離開 if (strUID == string.Empty) { tb.ShowBalloonTip("醫療系統資料庫查無此人", "請與杏翔系統連動, 或放棄操作", BalloonIcon.Warning); // activate hotkeys 2 Activate_Hotkeys(); log.Debug($"++ Exit F_LoadCompleted (2/5). NHI card inserted but no such person."); log.Info("==========================================================================="); log.Info($" "); return; } else { /// 表示讀卡成功 /// show balloon with built-in icon tb.ShowBalloonTip("讀卡成功", $"身分證號: {strUID}", BalloonIcon.Info); log.Info($" Successful NHI card read, VPN id: {strUID}."); /// 讀卡成功後做三件事: 讀特殊註記, 讀提醒, 開始準備讀所有資料 /// 2. 讀取提醒, 如果有的話 /// 這是在ContentPlaceHolder1_GV /// 也是個table IHTMLElement List_NHI_lab_reminder = d?.getElementById("ContentPlaceHolder1_GV"); if (List_NHI_lab_reminder != null) { HtmlDocument Html_NHI_lab_reminder = new HtmlDocument(); Html_NHI_lab_reminder.LoadHtml(List_NHI_lab_reminder?.outerHTML); // 寫入資料庫 foreach (HtmlNode tr in Html_NHI_lab_reminder.DocumentNode.SelectNodes("//table/tbody/tr")) { HtmlDocument h_ = new HtmlDocument(); h_.LoadHtml(tr.InnerHtml); HtmlNodeCollection tds = h_.DocumentNode.SelectNodes("//td"); if ((tds == null) || (tds.Count == 0)) { continue; } string Lab_Name = string.Empty, Last_Date = string.Empty; // tds[0] 是檢查(驗)項目類別名稱 Lab_Name = tds[0]?.InnerText; // tds[1] 是最近1次檢查日期 Last_Date = tds[1]?.InnerText; using (Com_clDataContext dc = new Com_clDataContext()) { var q1 = from p1 in dc.tbl_NHI_lab_reminder where (p1.uid == strUID) && (p1.lab_name == Lab_Name) && (p1.last_date == Last_Date) select p1; if (q1.Count() == 0) { tbl_NHI_lab_reminder newReminder = new tbl_NHI_lab_reminder() { uid = strUID, QDATE = DateTime.Now, lab_name = Lab_Name, last_date = Last_Date }; dc.tbl_NHI_lab_reminder.InsertOnSubmit(newReminder); dc.SubmitChanges(); } }; } } /// 準備: 初始化, 欄位基礎資料/位置, 可在windows生成時就完成 #region 準備 - 製造QueueOperation // Initialization QueueOperation?.Clear(); ListRetrieved?.Clear(); current_page = total_pages = 0; log.Info($" start reading Operation(s)."); // 讀取所有要讀的tab, 這些資料位於"ContentPlaceHolder1_tab" // IHTMLElement 無法轉型為 HTMLDocument // 20200429 tested successful IHTMLElement List_under_investigation = d?.getElementById("ContentPlaceHolder1_tab"); // li 之下就是 a List <string> balloonstring = new List <string>(); string BalloonTip = string.Empty; foreach (IHTMLElement hTML in List_under_investigation?.all) { if (tab_id_wanted.Contains(hTML.id)) { // 僅將要讀入的排入, 並沒有真的讀取資料 VPN_Operation vOP = VPN_Dictionary.Making_new_operation(hTML.id, strUID, DateTime.Now); QueueOperation.Enqueue(vOP); log.Info($" 讀入operation: {vOP.Short_Name}, [{strUID}]"); balloonstring.Add(vOP.Short_Name); } } for (int i = 0; i < balloonstring.Count; i++) { if (i == 0) { BalloonTip = balloonstring[i]; } else if ((i % 3) == 0) { BalloonTip += $";\r\n{balloonstring[i]}"; } else { BalloonTip += $"; {balloonstring[i]}"; } } log.Info($" end of Reading Operation(s), 共{QueueOperation?.Count}個Operation(s)."); #endregion 準備 - 製造QueueOperation #region 執行 if (QueueOperation.Count > 0) { // 流程控制, fm = framemonitor // 載入第一個operation //log.Info($" the first operation loaded."); current_op = QueueOperation.Dequeue(); tb.ShowBalloonTip($"開始讀取 [{current_op.UID}]", BalloonTip, BalloonIcon.Info); // 判斷第一個operation是否active, (小心起見, 其實應該不可能不active) // 不active就要按鍵 // 要注意class這個attribute是在上一層li層, 需把它改過來 if (d.getElementById(current_op.TAB_ID.Replace("_a_", "_li_")).className == "active") { // 由於此時沒有按鍵, 因此無法觸發LoadComplete, 必須人工觸發 fm.FrameLoadComplete += F_Data_LoadCompleted; log.Debug($"@@ Add delegate F_Data_LoadCompleted."); FrameLoadCompleteEventArgs ex = new FrameLoadCompleteEventArgs() { Message = FrameLoadStates.DirectCall }; log.Debug($"++ Exit F_LoadCompleted (3/5). Goto F_Data_LoadCompleted by direct call."); F_Data_LoadCompleted(this, ex); return; } else { // 不active反而可以用按鍵, 自動會觸發F_Data_LoadCompleted fm.FrameLoadComplete += F_Data_LoadCompleted; log.Debug($"@@ Add delegate F_Data_LoadCompleted."); // 20210719 有時候不fire Thread.Sleep(150); d.getElementById(current_op.TAB_ID).click(); log.Info($"[Action] push TAB {current_op.TAB_ID} Button."); log.Debug($"++ Exit F_LoadCompleted (4/5). Go to next tab by pushing tab button."); return; } } else { // 做個紀錄 // 一個都沒有 log.Info($" no record at all."); tb.ShowBalloonTip("沒有資料", "健保資料庫裡沒有資料可讀取", BalloonIcon.Info); // 製作紀錄by rd tbl_Query2 q = new tbl_Query2() { uid = strUID, QDATE = DateTime.Now, cloudmed_N = 0, cloudlab_N = 0, schedule_N = 0, op_N = 0, dental_N = 0, allergy_N = 0, discharge_N = 0, rehab_N = 0, tcm_N = 0 }; using (Com_clDataContext dc = new Com_clDataContext()) { dc.tbl_Query2.InsertOnSubmit(q); dc.SubmitChanges(); }; // activate hotkeys 3 Activate_Hotkeys(); log.Debug($"++ Exit F_LoadCompleted (5/5). NHI inserted and verified but completey no data."); log.Info("==========================================================================="); log.Info($" "); } #endregion 執行 } }
private void F_Pager_LoadCompleted(object sender, FrameLoadCompleteEventArgs e) { log.Debug($"++ Entered F_Pager_LoadCompleted from {e.Message}"); if (e.Message == FrameLoadStates.DocumentLoadCompletedButNotFrame) { return; } log.Debug($"@@ delete delegate F_Pager_LoadComplated. [{current_op?.UID}]"); fm.FrameLoadComplete -= F_Pager_LoadCompleted; // 每當刷新後都要重新讀一次 // d 是parent HTML document HTMLDocument d = (HTMLDocument)g.Document; // f 是frame(0) HTML document HTMLDocument f = d.frames.item(0).document.body.document; // 讀取資料 foreach (Target_Table tt in current_op.Target) { // 這裡不用管多table, 因為多table只發生在管制藥那裏 ListRetrieved.Add(new VPN_Retrieved(tt.Short_Name, tt.Header_Want, f.getElementById(tt.TargetID).outerHTML, current_op.UID, current_op.QDate)); SaveHTML($"{tt.Short_Name}_{current_op.UID}", f.getElementById(tt.TargetID).outerHTML); } log.Info($"[Action] Reading HTML: {current_op.Short_Name}, [{current_op.UID}]. page: {current_page}/{total_pages}"); // 判斷是否最後一頁, 最後一tab if ((current_page == total_pages) && (QueueOperation.Count == 0)) { // 兩個出口之一, 最後一個tab, 另一個出口是, 最後一個tab, 同時有其他page且為最後一頁, // 另一個在F_Data_LoadCompleted // 最後一頁 // 處理index current_page = total_pages = 0; // 20200506: current_op 歸零似乎是不行的 //current_op = null; // 20210719: 將QDATE設定為1901/1/1, 是傳達這是最後一頁了, 設定在F_Pager_LoadCompleted // 20210719: 移除這個愚蠢的方法 //current_op.QDate = DateTime.Parse("1901/01/01"); //// 這是沒有用的add delegate, 但是為了平衡, 避免可能的錯誤 //fm.FrameLoadComplete += F_Data_LoadCompleted; //log.Info(" add delegate F_Data_LoadCompleted."); //// 沒有按鍵無法直接觸發, 只好直接呼叫 //FrameLoadCompleteEventArgs ex = new FrameLoadCompleteEventArgs() //{ // Message = FrameLoadStates.DirectCall //}; //F_Data_LoadCompleted(this, ex); // 此段程式的一個出口點 // 20210719: 讀完實體資料就開始解析HTML吧 string o = $"++ Exit F_Pager_LoadCompleted (1/3). last page, last tab, go to finalization directly. [{current_op.UID}]"; ParsingTables(o); return; } else if (current_page == total_pages) { // 最後一頁 // 處理index current_page = total_pages = 0; // 轉軌 fm.FrameLoadComplete += F_Data_LoadCompleted; log.Debug($"@@ add delegate F_Data_LoadCompleted. [{current_op.UID}]"); Thread.Sleep(150); // 下一個tab log.Info($"[Action] {current_op.TAB_ID} tab key pressed."); current_op = QueueOperation.Dequeue(); log.Debug($"++ Exit F_Pager_LoadCompleted (2/3). last page, go to next tab by clicking. [{current_op.UID}]"); d.getElementById(current_op.TAB_ID).click(); // 此段程式的一個出口點 return; } else { current_page++; // 按鍵到下一頁, 此段程式到此結束 // HOW TO ????????????????????????????????????????? // 如何下一頁, 可能要用invokescript // 按鈕機制 fm.FrameLoadComplete += F_Pager_LoadCompleted; log.Debug($"@@ add delegate F_Pager_LoadCompleted. [{current_op.UID}]"); Thread.Sleep(150); log.Info($"[Action] 下一頁按下去了.(多頁) [{current_op.UID}]"); log.Debug($"++ Exit F_Pager_LoadCompleted (3/3). go to next page by clicking. [{current_op.UID}]"); foreach (IHTMLElement a in f.getElementById("ContentPlaceHolder1_pg_gvList").all) { if (a.innerText == ">") { a.click(); } } // 此段程式的一個出口點 return; } }
public void DequeueAlarmInfoTest(string no, string in_InitializeSqlSet, string in_QueueItem, string expected_MailQueueSet, string expected_TableData, string expected_FailureBlobFileSet, string expected_LogMessages, string remarks) { List <TestLog> actual_logs = new List <TestLog>(); // DI DependencyInjection(DefaultAppSettingValues, actual_logs); // テストデータ準備 { if (Directory.Exists(in_InitializeSqlSet)) { // 設置ベースデータテーブル、機器データテーブルを先に設定する PresetDb(); using (SqlConnection connection = new SqlConnection(settings.PrimaryDbConnectionString)) { try { connection.Open(); foreach (string path in Directory.GetFiles(in_InitializeSqlSet, "*.sql", SearchOption.AllDirectories)) { string cmdText = File.ReadAllText(path); using (SqlCommand command = new SqlCommand(cmdText, connection)) { command.ExecuteNonQuery(); } } } finally { connection.Close(); } } } in_QueueItem = (in_QueueItem != null && File.Exists(in_QueueItem)) ? File.ReadAllText(in_QueueItem) : in_QueueItem; } // テスト実行後、テーブルを評価するかどうか bool isCheckTable = !string.IsNullOrEmpty(expected_TableData) && File.Exists(expected_TableData); // 評価対象テーブル名 string targetTableName = isCheckTable ? Path.GetFileNameWithoutExtension(expected_TableData) : null; // 期待値 List <string> expected_queues = Directory.Exists(expected_MailQueueSet) ? Directory.GetFiles(expected_MailQueueSet, "*.json").Select(x => File.ReadAllText(x)).ToList() : new List <string>(); DataTable expected_table = isCheckTable ? DataTableHelper.SelectCsv(settings.PrimaryDbConnectionString, expected_TableData, targetTableName) : null; DirectoryInfo expectedFailureDir = new DirectoryInfo(expected_FailureBlobFileSet); string[] expectedFailureFiles = expectedFailureDir.Exists ? expectedFailureDir.GetFiles("*", SearchOption.AllDirectories).Select(x => x.FullName).OrderBy(x => x).ToArray() : new string[] { }; string[] expected_failure_names = expectedFailureFiles.Select(x => x.Replace(expectedFailureDir.FullName, string.Empty)).ToArray(); string[] expected_failure_contents = expectedFailureFiles.Select(x => File.ReadAllText(x)).ToArray(); List <string> expected_log_messages = (expected_LogMessages != null && File.Exists(expected_LogMessages)) ? File.ReadLines(expected_LogMessages).ToList() : new List <string>(); // テスト実行 target.DequeueAlarmInfo(in_QueueItem, new TestLogger <AlarmRegisterController>(actual_logs)); // テスト結果 List <string> actual_queses = QueueOperation.GetMessages(settings.MailQueueName, settings.MailQueueConnectionString); DataTable actual_table = isCheckTable ? DataTableHelper.SelectTable(settings.PrimaryDbConnectionString, "SELECT * FROM " + targetTableName) : null; DirectoryInfo actualDir = new DirectoryInfo(Path.Combine(TestResultRootDir, no)); string[] actualFailureFiles = failureBlob.Client.GetFiles(settings.FailureBlobContainerName, actualDir).OrderBy(x => x).ToArray(); string[] actual_failure_names = actualFailureFiles.Select(x => x.Replace(actualDir.FullName, string.Empty)).ToArray(); string[] actual_failure_contents = actualFailureFiles.Select(x => File.ReadAllText(x)).ToArray(); List <string> actual_log_messages = actual_logs.Select(x => x.GetSimpleText()).ToList(); // 確認(メールキュー) CollectionAssert.AreEqual(expected_queues, actual_queses); // 確認(DT_ALARM) if (isCheckTable) { // 評価対象外のカラムを除外 Array.ForEach(IgnoreColumns, x => expected_table.Columns.Remove(x)); Array.ForEach(IgnoreColumns, x => actual_table.Columns.Remove(x)); Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(expected_table.Rows.Count, actual_table.Rows.Count); // 日付は期待値読み込み時に日本時刻で取得されてしまうため別に比較する foreach (var columnName in DateTimeColumns) { var exptected_datetime_table = expected_table.DefaultView.ToTable(false, columnName); var actual_datetime_table = actual_table.DefaultView.ToTable(false, columnName); for (int i = 0; i < exptected_datetime_table.Rows.Count; i++) { var expected_datetime = ((DateTime)exptected_datetime_table.Rows[i].ItemArray[0]).ToUniversalTime(); var actual_datetime = (DateTime)actual_datetime_table.Rows[i].ItemArray[0]; Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(expected_datetime, actual_datetime); } // 評価したカラムを除外 expected_table.Columns.Remove(columnName); actual_table.Columns.Remove(columnName); } for (int i = 0; i < expected_table.Rows.Count; i++) { CollectionAssert.AreEqual(expected_table.Rows[i].ItemArray, actual_table.Rows[i].ItemArray); } } // 確認(Failureブロブ) CollectionAssert.AreEqual(expected_failure_names, actual_failure_names); CollectionAssert.AreEqual(expected_failure_contents, actual_failure_contents); // 確認(ログ) foreach (var expected_log_message in expected_log_messages) { var matching_element = actual_log_messages.FirstOrDefault(actual => actual.Contains(expected_log_message)); Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotNull(matching_element, string.Format("「{0}」に一致する要素が見つかりません", expected_log_message)); if (matching_element != null) { actual_log_messages.Remove(matching_element); } } }
public void ReceiveDiskDriveTest(string no, string in_InitializeSqlSet, string in_Message, string expected_AlarmQueueSet, string expected_TableData, string expected_FailureBlobFileSet, string expected_LogMessages, string remarks) { List <TestLog> actual_logs = new List <TestLog>(); // DI DependencyInjection(DefaultAppSettingValues, actual_logs); // テストデータ準備 { if (Directory.Exists(in_InitializeSqlSet)) { using (SqlConnection connection = new SqlConnection(settings.PrimaryDbConnectionString)) { try { connection.Open(); foreach (string path in Directory.GetFiles(in_InitializeSqlSet, "*.sql", SearchOption.AllDirectories)) { string cmdText = File.ReadAllText(path); using (SqlCommand command = new SqlCommand(cmdText, connection)) { command.ExecuteNonQuery(); } } } finally { connection.Close(); } } } in_Message = (in_Message != null && File.Exists(in_Message)) ? File.ReadAllText(in_Message) : in_Message; } // テスト実行後、テーブルを評価するかどうか bool isCheckTable = !string.IsNullOrEmpty(expected_TableData) && File.Exists(expected_TableData); // 評価対象テーブル名 string targetTableName = isCheckTable ? Path.GetFileNameWithoutExtension(expected_TableData) : null; // 期待値 List <string> expected_queues = Directory.Exists(expected_AlarmQueueSet) ? Directory.GetFiles(expected_AlarmQueueSet, "*.json").Select(x => File.ReadAllText(x)).ToList() : new List <string>(); DataTable expected_table = isCheckTable ? DataTableHelper.SelectCsv(settings.PrimaryDbConnectionString, expected_TableData, targetTableName) : null; DirectoryInfo expectedFailureDir = new DirectoryInfo(expected_FailureBlobFileSet); string[] expectedFailureFiles = expectedFailureDir.Exists ? expectedFailureDir.GetFiles("*", SearchOption.AllDirectories).Select(x => x.FullName).OrderBy(x => x).ToArray() : new string[] { }; string[] expected_failure_names = expectedFailureFiles.Select(x => x.Replace(expectedFailureDir.FullName, string.Empty)).ToArray(); string[] expected_failure_contents = expectedFailureFiles.Select(x => File.ReadAllText(x)).ToArray(); List <string> expected_log_messages = (expected_LogMessages != null && File.Exists(expected_LogMessages)) ? File.ReadLines(expected_LogMessages).ToList() : new List <string>(); // テスト実行 target.ReceiveDiskDrive(in_Message, new TestLogger <DiskDrivePremonitorController>(actual_logs)); // テスト結果 List <string> actual_queses = QueueOperation.GetMessages(settings.AlarmQueueName, settings.QueueStorageConnectionString); DataTable actual_table = isCheckTable ? DataTableHelper.SelectTable(settings.PrimaryDbConnectionString, "SELECT * FROM " + targetTableName) : null; DirectoryInfo actualDir = new DirectoryInfo(Path.Combine(TestResultRootDir, no)); string[] actualFailureFiles = failureBlob.Client.GetFiles(settings.FailureBlobContainerName, actualDir).OrderBy(x => x).ToArray(); string[] actual_failure_names = actualFailureFiles.Select(x => x.Replace(actualDir.FullName, string.Empty)).ToArray(); string[] actual_failure_contents = actualFailureFiles.Select(x => File.ReadAllText(x)).ToArray(); List <string> actual_log_messages = actual_logs.Select(x => x.GetSimpleText()).ToList(); // 確認(アラームキュー) CollectionAssert.AreEqual(expected_queues, actual_queses); // 確認(DT_SMART_ANALYSIS_RESULT) if (isCheckTable) { Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(expected_table.Rows.Count, actual_table.Rows.Count); for (int i = 0; i < expected_table.Rows.Count; i++) { CollectionAssert.AreEqual(expected_table.Rows[i].ItemArray, actual_table.Rows[i].ItemArray); } } // 確認(Failureブロブ) CollectionAssert.AreEqual(expected_failure_names, actual_failure_names); CollectionAssert.AreEqual(expected_failure_contents, actual_failure_contents); // 確認(ログ) foreach (var expected_log_message in expected_log_messages) { var matching_element = actual_log_messages.FirstOrDefault(actual => actual.Contains(expected_log_message)); Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotNull(matching_element, string.Format("「{0}」に一致する要素が見つかりません", expected_log_message)); if (matching_element != null) { actual_log_messages.Remove(matching_element); } } }
private void F_Data_LoadCompleted(object sender, FrameLoadCompleteEventArgs e) { log.Debug($"++ Enter F_Data_LoadCompleted from {e.Message}."); if (e.Message == FrameLoadStates.DocumentLoadCompletedButNotFrame) { return; } // 每當刷新後都要重新讀一次 // d 是parent HTML document HTMLDocument d = (HTMLDocument)g.Document; #region 感知目前位置, 與current_op比較, 如果不是,就還是要再按一次 // 目標: current_op.TAB_ID // 實際: d.getElementById(current_op.TAB_ID.Replace("_a_", "_li_")).className == "active" if (d.getElementById(current_op.TAB_ID.Replace("_a_", "_li_")).className != "active") { // 不active反而可以用按鍵, 自動會觸發F_Data_LoadCompleted // 20210719 有時候不fire Thread.Sleep(150); d.getElementById(current_op.TAB_ID).click(); log.Info($"[Action] push TAB {current_op.TAB_ID} Button."); log.Debug($"++ Exit F_Data_LoadCompleted (1/4). Not in the right page, click again."); return; } #endregion /// 20210719: 將QDATE設定為1901/1/1, 是傳達這是最後一頁了, 設定在F_Pager_LoadCompleted /// 20210719: 刪除掉蠢蠢的current_op?.QDate = 1901/1/1 ///if (current_op?.QDate == DateTime.Parse("1901/01/01")) ///{ /// // 不用再讀取資料了, 直接到存入資料庫部分 /// log.Info($"Entered F_Data_LoadCompleted, {current_op?.UID} 已經讀完所有資料, 最後存入資料庫."); ///} ///else ///{ /// 還需要讀取資料 log.Info($"Current OP: {current_op?.UID} {current_op?.Short_Name}"); //} log.Debug($"@@ delete delegate F_Data_LoadComplated. [{current_op?.UID}]"); fm.FrameLoadComplete -= F_Data_LoadCompleted; // 這時候已經確保是 active // f 是frame(0) HTML document HTMLDocument f = d?.frames.item(0).document.body.document; /// 3. 網頁操弄與擷取資料: sequential /// 3-1. 判斷分頁, 有幾頁, 現在在第幾頁, 換頁不會觸發LoadCompleted; 疑問會不會來不及? -done /// 3-2. 要先排序, 排序也不會觸發LoadCompleted; 疑問會不會來不及? -done, 不用再管排序 /// 3-2. 都放在記憶體裡, 快速, in the LIST /// // special remark: current_op.QDate set to null 是表示來自多頁結束那裏 // 20210719: 將QDATE設定為1901/1/1, 是傳達這是最後一頁了, 設定在F_Pager_LoadCompleted // 20210719: 刪除掉蠢蠢的current_op?.QDate = 1901/1/1 //if ((current_op != null) && (current_op?.QDate != DateTime.Parse("1901/01/01"))) if (current_op != null) { // 表示不是最後一頁, 還要讀取資料 log.Info($"[Action] Reading HTML: {current_op.Short_Name}, [{current_op?.UID}]"); #region 讀取資料, 存入記憶體, 存入檔案 foreach (Target_Table tt in current_op.Target) { // 是否有多tables, 端看tt.Children, 除了管制藥物外, 其餘都不用 if (tt.Children == null) { try { // 20210718: 好像就是這裏出了問題 ListRetrieved.Add(new VPN_Retrieved(tt.Short_Name, tt.Header_Want, f.getElementById(tt.TargetID).outerHTML, current_op.UID, current_op.QDate)); // 20200606 stop recording tables in html // 20210716 resume recording tables in html SaveHTML($"{tt.Short_Name}_{current_op.UID}", f.getElementById(tt.TargetID).outerHTML); } catch (Exception ex) { // 存入空的HTML ListRetrieved.Add(new VPN_Retrieved(tt.Short_Name, tt.Header_Want, "", current_op.UID, current_op.QDate)); log.Error($" Failed to read html. From: {tt.Short_Name}. Error: {ex.Message}"); } } else { // 有多個table, 使用情形僅有管制藥物 ListRetrieved.Add(new VPN_Retrieved(tt.Short_Name, tt.Header_Want, f.getElementById(tt.TargetID).children(tt.Children).outerHTML, current_op.UID, current_op.QDate)); SaveHTML($"{tt.Short_Name}_{tt.Children}_{current_op.UID}", f.getElementById(tt.TargetID).outerHTML); } } #endregion 讀取資料, 存入記憶體, 存入檔案 #region 判斷多頁 // 目前重點, 如何判斷多頁? // 設定total_pages = ???? HtmlDocument p = new HtmlDocument(); if (f.getElementById(@"ctl00$ContentPlaceHolder1$pg_gvList_input") == null) { log.Info($"[Info] Only one page detected, {current_op?.UID} {current_op?.Short_Name}."); total_pages = 1; } else { // 如果多頁, 轉換loadcomplete, 呼叫pager by click // 20200502: outerHTML的XPATH="//selection/option", innerHTML的XPATH="//option" p.LoadHtml(f.getElementById(@"ctl00$ContentPlaceHolder1$pg_gvList_input").innerHTML); HtmlNodeCollection o = p.DocumentNode.SelectNodes("//option"); total_pages = o.Count; log.Info($"[Info] {total_pages} pages detected, {current_op?.UID} {current_op?.Short_Name}"); // 剛剛已經讀了第一頁了, 從下一頁開始 current_page = 2; // 按鈕機制 fm.FrameLoadComplete += F_Pager_LoadCompleted; // 轉軌 log.Debug($"@@ add delegate F_Pager_LoadCompleted."); Thread.Sleep(150); foreach (IHTMLElement a in f.getElementById("ContentPlaceHolder1_pg_gvList").all) { if (a.innerText == ">") { log.Info("[Action] 按了下一頁."); log.Debug($"++ Exit F_Data_LoadCompleted (2/4). Multipage, go to next page."); a.click(); // 20200504 發現這裡執行完後還會執行後面的程序, 造成兩個程序的衝突 // 此段程式的一個出口點 return; } } } #endregion 判斷多頁 } // 判斷是否最後一tab, 程序群的出口 if (QueueOperation.Count == 0) { // 兩個出口之一, 最後一個tab, 另一個出口是, 最後一個tab, 同時沒有其他page, 另一個在F_Pager_LoadCompleted // 20210719: 讀完實體資料就開始解析HTML吧 string o = $"++ Exit F_Data_LoadCompleted (3/4). The REAL END! [{current_op.UID}]"; ParsingTables(o); return; } else { // 下一個tab current_op = QueueOperation.Dequeue(); fm.FrameLoadComplete += F_Data_LoadCompleted; log.Debug($"@@ add delegate F_Data_LoadCompleted. [{current_op.UID}]"); Thread.Sleep(150); d.getElementById(current_op.TAB_ID).click(); log.Debug($"[Action] {current_op.TAB_ID} tab key pressed. [{current_op.UID}]"); log.Debug($"++ Exit F_Data_LoadCompleted (4/4). Go to next tab. {QueueOperation.Count + 1} tabs to go.. [{current_op.UID}]"); return; } }
public void MonitorAlmilogAnalysisResultTableTest(string no, string in_InitializeSqlSet, string expected_AlarmQueueSet, string expected_TableData, string expected_LogMessages, string remarks) { List <TestLog> actual_logs = new List <TestLog>(); // DI DependencyInjection(DefaultAppSettingValues, actual_logs); // テストデータ準備 { if (Directory.Exists(in_InitializeSqlSet)) { using (SqlConnection connection = new SqlConnection(settings.PrimaryDbConnectionString)) { try { connection.Open(); foreach (string path in Directory.GetFiles(in_InitializeSqlSet, "*.sql", SearchOption.AllDirectories)) { string cmdText = File.ReadAllText(path); using (SqlCommand command = new SqlCommand(cmdText, connection)) { command.ExecuteNonQuery(); } } } finally { connection.Close(); } } } } // テスト実行後、テーブルを評価するかどうか bool isCheckTable = !string.IsNullOrEmpty(expected_TableData) && File.Exists(expected_TableData); // 評価対象テーブル名 string targetTableName = isCheckTable ? Path.GetFileNameWithoutExtension(expected_TableData) : null; // 期待値 DataTable expected_table = isCheckTable ? DataTableHelper.SelectCsv(settings.PrimaryDbConnectionString, expected_TableData, targetTableName) : null; List <string> expected_queues = Directory.Exists(expected_AlarmQueueSet) ? Directory.GetFiles(expected_AlarmQueueSet, "*.json").Select(x => File.ReadAllText(x)).ToList() : new List <string>(); List <string> expected_log_messages = (expected_LogMessages != null && File.Exists(expected_LogMessages)) ? File.ReadLines(expected_LogMessages).ToList() : new List <string>(); // テスト実行 target.MonitorAlmilogAnalysisResultTable(null, new TestLogger <DipAlmiLogPremonitorController>(actual_logs)); // テスト結果 DataTable actual_table = isCheckTable ? DataTableHelper.SelectTable(settings.PrimaryDbConnectionString, "SELECT * FROM " + targetTableName) : null; List <string> actual_queses = QueueOperation.GetMessages(settings.AlarmQueueName, settings.QueueStorageConnectionString); List <string> actual_log_messages = actual_logs.Select(x => x.GetSimpleText()).ToList(); // 確認 CollectionAssert.AreEqual(expected_queues, actual_queses); if (isCheckTable) { Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(expected_table.Rows.Count, actual_table.Rows.Count); for (int i = 0; i < expected_table.Rows.Count; i++) { CollectionAssert.AreEqual(expected_table.Rows[i].ItemArray, actual_table.Rows[i].ItemArray); } } foreach (var expected_log_message in expected_log_messages) { var matching_element = actual_log_messages.FirstOrDefault(actual => actual.Contains(expected_log_message)); Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotNull(matching_element, string.Format("「{0}」に一致する要素が見つかりません", expected_log_message)); if (matching_element != null) { actual_log_messages.Remove(matching_element); } } }
public static QueueEventArgs Create(string id, Visitor visitor, QueueType type, QueueOperation operation) { return(new QueueEventArgs { Id = id, Operation = operation, Type = type, Visitor = visitor }); }