processor_test.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
  1. /*
  2. * ECAL
  3. *
  4. * Copyright 2020 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the MIT
  7. * License, If a copy of the MIT License was not distributed with this
  8. * file, You can obtain one at https://opensource.org/licenses/MIT.
  9. */
  10. package engine
  11. import (
  12. "bytes"
  13. "errors"
  14. "fmt"
  15. "os"
  16. "sync"
  17. "testing"
  18. "time"
  19. "devt.de/krotik/common/errorutil"
  20. "devt.de/krotik/ecal/engine/pool"
  21. )
  22. func TestProcessorSimpleCascade(t *testing.T) {
  23. UnitTestResetIDs()
  24. // Add debug logging
  25. var debugBuffer bytes.Buffer
  26. EventTracer.out = &debugBuffer
  27. EventTracer.MonitorEvent("core.*", map[interface{}]interface{}{
  28. "foo": "bar",
  29. "foo2": nil,
  30. })
  31. EventTracer.MonitorEvent("core.*", map[interface{}]interface{}{
  32. "foo2": "test",
  33. })
  34. defer func() {
  35. EventTracer.Reset()
  36. EventTracer.out = os.Stdout
  37. }()
  38. // Do the normal testing
  39. var log bytes.Buffer
  40. proc := NewProcessor(1)
  41. StderrSave := os.Stderr
  42. os.Stderr = nil
  43. proc.ThreadPool().TooManyCallback()
  44. os.Stderr = StderrSave
  45. if res := fmt.Sprint(proc); res != "EventProcessor 1 (workers:1)" {
  46. t.Error("Unexpected result:", res)
  47. return
  48. }
  49. // Add rules to the processor
  50. rule1 := &Rule{
  51. "TestRule1", // Name
  52. "", // Description
  53. []string{"core.main.event1"}, // Kind match
  54. []string{"data"}, // Match on event cascade scope
  55. nil, // No state match
  56. 2, // Priority of the rule
  57. []string{"TestRule3", "TestRule3Copy"}, // List of suppressed rules by this rule
  58. func(p Processor, m Monitor, e *Event, tid uint64) error { // Action of the rule
  59. log.WriteString("TestRule1\n")
  60. // Add another event
  61. p.AddEvent(&Event{
  62. "InitialEvent",
  63. []string{"core", "main", "event2"},
  64. map[interface{}]interface{}{
  65. "foo": "bar",
  66. "foo2": "bla",
  67. },
  68. }, m.NewChildMonitor(1))
  69. return nil
  70. },
  71. }
  72. rule2 := &Rule{
  73. "TestRule2", // Name
  74. "", // Description
  75. []string{"core.main.*"}, // Kind match
  76. []string{"data.read"}, // Match on event cascade scope
  77. nil, // No state match
  78. 5, // Priority of the rule
  79. nil, // List of suppressed rules by this rule
  80. func(p Processor, m Monitor, e *Event, tid uint64) error { // Action of the rule
  81. log.WriteString("TestRule2\n")
  82. return nil
  83. },
  84. }
  85. rule3 := &Rule{
  86. "TestRule3", // Name
  87. "", // Description
  88. []string{"core.main.*"}, // Kind match
  89. []string{"data.read"}, // Match on event cascade scope
  90. nil, // No state match
  91. 0, // Priority of the rule
  92. nil, // List of suppressed rules by this rule
  93. func(p Processor, m Monitor, e *Event, tid uint64) error { // Action of the rule
  94. log.WriteString("TestRule3\n")
  95. return nil
  96. },
  97. }
  98. proc.AddRule(rule1)
  99. proc.AddRule(rule2)
  100. proc.AddRule(rule3)
  101. if r := len(proc.Rules()); r != 3 {
  102. t.Error("Unexpected rule number:", r)
  103. return
  104. }
  105. // Start the processor
  106. proc.Start()
  107. // Push a root event
  108. e := NewEvent(
  109. "InitialEvent",
  110. []string{"core", "main", "event1"},
  111. map[interface{}]interface{}{
  112. "foo": "bar",
  113. "foo2": "bla",
  114. },
  115. )
  116. if e.Name() != e.name || e.Kind() == nil || e.State() == nil {
  117. t.Error("Unepxected getter result:", e)
  118. return
  119. }
  120. rootm := proc.NewRootMonitor(nil, nil)
  121. rootm.SetFinishHandler(func(p Processor) {
  122. log.WriteString("finished!")
  123. })
  124. proc.AddEventAndWait(e, rootm)
  125. if err := proc.AddRule(rule3); err.Error() != "Cannot add rule if the processor has not stopped" {
  126. t.Error("Unexpected error:", err)
  127. return
  128. }
  129. if err := proc.Reset(); err.Error() != "Cannot reset processor if it has not stopped" {
  130. t.Error("Unexpected error:", err)
  131. return
  132. }
  133. // Finish the processor
  134. proc.Finish()
  135. // Finish the processor
  136. // Rule 1, 2 and 3 trigger on event1 but rule 3 is suppressed by rule 1
  137. // Rule 1 adds a new event which triggers only rule 2 and 3
  138. // Rule 3 comes first since it has the higher priority
  139. if log.String() != `TestRule1
  140. TestRule2
  141. TestRule3
  142. TestRule2
  143. finished!` {
  144. t.Error("Unexpected result:", log.String())
  145. return
  146. }
  147. log.Reset()
  148. if err := proc.AddRule(rule3.CopyAs("TestRule3Copy")); err != nil {
  149. t.Error("Unexpected error:", err)
  150. return
  151. }
  152. // Start the processor
  153. proc.Start()
  154. // Push a root event
  155. proc.AddEventAndWait(&Event{
  156. "InitialEvent",
  157. []string{"core", "main", "event1"},
  158. nil,
  159. }, nil)
  160. // Finish the processor
  161. proc.Finish()
  162. if log.String() != `TestRule1
  163. TestRule2
  164. TestRule3
  165. TestRule3
  166. TestRule2
  167. ` {
  168. t.Error("Unexpected result:", log.String())
  169. return
  170. }
  171. // Test the case when the event is pointless
  172. log.Reset()
  173. proc.Start()
  174. proc.AddEvent(&Event{
  175. "InitialEventFoo",
  176. []string{"core", "foo", "event1"},
  177. nil,
  178. }, nil)
  179. rm := proc.NewRootMonitor(nil, nil)
  180. proc.AddEvent(&Event{
  181. "InitialEventFoo",
  182. []string{"core", "foo", "event1"},
  183. nil,
  184. }, rm)
  185. if !rm.IsFinished() {
  186. t.Error("Monitor which monitored a non-triggering event should still finished")
  187. return
  188. }
  189. proc.Finish()
  190. if log.String() != "" {
  191. t.Error("Unexpected result:", log.String())
  192. return
  193. }
  194. proc.Reset()
  195. if r := len(proc.Rules()); r != 0 {
  196. t.Error("Unexpected rule number:", r)
  197. return
  198. }
  199. if debugBuffer.String() == "" {
  200. t.Error("Nothing was recorded in the debug buffer")
  201. return
  202. }
  203. }
  204. func TestProcessorSimplePriorities(t *testing.T) {
  205. UnitTestResetIDs()
  206. var logLock = sync.Mutex{}
  207. var log bytes.Buffer
  208. testPriorities := func(p1, p2 int) int {
  209. proc := NewProcessor(2)
  210. // Add rules to the processor
  211. rule1 := &Rule{
  212. "TestRule1", // Name
  213. "", // Description
  214. []string{"core.main.event1"}, // Kind match
  215. []string{"data"}, // Match on event cascade scope
  216. nil, // No state match
  217. 0, // Priority of the rule
  218. nil, // List of suppressed rules by this rule
  219. func(p Processor, m Monitor, e *Event, tid uint64) error { // Action of the rule
  220. logLock.Lock()
  221. log.WriteString("TestRule1\n")
  222. logLock.Unlock()
  223. time.Sleep(2 * time.Millisecond)
  224. return nil
  225. },
  226. }
  227. rule2 := &Rule{
  228. "TestRule2", // Name
  229. "", // Description
  230. []string{"core.main.event2"}, // Kind match
  231. []string{"data"}, // Match on event cascade scope
  232. nil, // No state match
  233. 0, // Priority of the rule
  234. nil, // List of suppressed rules by this rule
  235. func(p Processor, m Monitor, e *Event, tid uint64) error { // Action of the rule
  236. logLock.Lock()
  237. log.WriteString("TestRule2\n")
  238. logLock.Unlock()
  239. time.Sleep(2 * time.Millisecond)
  240. return nil
  241. },
  242. }
  243. proc.AddRule(rule1)
  244. proc.AddRule(rule2)
  245. proc.Start()
  246. m := proc.NewRootMonitor(nil, nil)
  247. // Push a root event
  248. for i := 0; i < 3; i++ {
  249. proc.AddEvent(&Event{
  250. "InitialEvent1",
  251. []string{"core", "main", "event1"},
  252. nil,
  253. }, m.NewChildMonitor(p1))
  254. }
  255. proc.AddEvent(&Event{
  256. "InitialEvent2",
  257. []string{"core", "main", "event2"},
  258. nil,
  259. }, m.NewChildMonitor(p2))
  260. proc.AddEvent(&Event{
  261. "InitialEvent1",
  262. []string{"core", "main", "event1"},
  263. nil,
  264. }, m.NewChildMonitor(p1))
  265. hp := m.HighestPriority()
  266. // Finish the processor
  267. proc.Finish()
  268. errorutil.AssertTrue(m.HighestPriority() == -1,
  269. "Highest priority should be -1 once a monitor has finished")
  270. return hp
  271. }
  272. // Since rule 1 has the higher priority it is more likely to be
  273. // executed
  274. if res := testPriorities(3, 5); res != 3 {
  275. t.Error("Unexpected highest priority:", res)
  276. return
  277. }
  278. if log.String() != `TestRule1
  279. TestRule1
  280. TestRule1
  281. TestRule1
  282. TestRule2
  283. ` && log.String() != `TestRule1
  284. TestRule1
  285. TestRule1
  286. TestRule2
  287. TestRule1
  288. ` {
  289. t.Error("Unexpected result:", log.String())
  290. return
  291. }
  292. log.Reset()
  293. // Since rule 2 has the higher priority it is more likely to be
  294. // executed
  295. if res := testPriorities(5, 2); res != 2 {
  296. t.Error("Unexpected highest priority:", res)
  297. return
  298. }
  299. if log.String() != `TestRule2
  300. TestRule1
  301. TestRule1
  302. TestRule1
  303. TestRule1
  304. ` && log.String() != `TestRule1
  305. TestRule2
  306. TestRule1
  307. TestRule1
  308. TestRule1
  309. ` && log.String() != `TestRule1
  310. TestRule1
  311. TestRule2
  312. TestRule1
  313. TestRule1
  314. ` {
  315. t.Error("Unexpected result:", log.String())
  316. return
  317. }
  318. }
  319. func TestProcessorScopeHandling(t *testing.T) {
  320. UnitTestResetIDs()
  321. var logLock = sync.Mutex{}
  322. var log bytes.Buffer
  323. proc := NewProcessor(10)
  324. // Add rules to the processor
  325. rule1 := &Rule{
  326. "TestRule1", // Name
  327. "", // Description
  328. []string{"core.main.*"}, // Kind match
  329. []string{"data.write"}, // Match on event cascade scope
  330. nil, // No state match
  331. 0, // Priority of the rule
  332. nil, // List of suppressed rules by this rule
  333. func(p Processor, m Monitor, e *Event, tid uint64) error { // Action of the rule
  334. logLock.Lock()
  335. log.WriteString("TestRule1\n")
  336. logLock.Unlock()
  337. time.Sleep(2 * time.Millisecond)
  338. return nil
  339. },
  340. }
  341. rule2 := &Rule{
  342. "TestRule2", // Name
  343. "", // Description
  344. []string{"core.main.*"}, // Kind match
  345. []string{"data"}, // Match on event cascade scope
  346. nil, // No state match
  347. 0, // Priority of the rule
  348. nil, // List of suppressed rules by this rule
  349. func(p Processor, m Monitor, e *Event, tid uint64) error { // Action of the rule
  350. logLock.Lock()
  351. log.WriteString("TestRule2\n")
  352. logLock.Unlock()
  353. time.Sleep(2 * time.Millisecond)
  354. return nil
  355. },
  356. }
  357. proc.AddRule(rule1)
  358. proc.AddRule(rule2)
  359. if proc.Status() != pool.StatusStopped || !proc.Stopped() {
  360. t.Error("Unexpected status:", proc.Status(), proc.Stopped())
  361. return
  362. }
  363. proc.Start()
  364. if proc.Status() != pool.StatusRunning || proc.Stopped() {
  365. t.Error("Unexpected status:", proc.Status(), proc.Stopped())
  366. return
  367. }
  368. scope1 := NewRuleScope(map[string]bool{
  369. "data": true,
  370. "data.read": true,
  371. "data.write": false,
  372. })
  373. m := proc.NewRootMonitor(nil, scope1)
  374. // Push a root event
  375. proc.AddEvent(&Event{
  376. "InitialEvent",
  377. []string{"core", "main", "event1"},
  378. nil,
  379. }, m)
  380. // Finish the processor
  381. proc.Finish()
  382. // Only rule 2 should trigger since the monitor has only access
  383. // to data and data.read
  384. if log.String() != `TestRule2
  385. ` {
  386. t.Error("Unexpected result:", log.String())
  387. return
  388. }
  389. log.Reset()
  390. proc.Start()
  391. scope2 := NewRuleScope(map[string]bool{
  392. "data": true,
  393. "data.read": true,
  394. "data.write": true,
  395. })
  396. m = proc.NewRootMonitor(nil, scope2)
  397. // Push a root event
  398. proc.AddEvent(&Event{
  399. "InitialEvent",
  400. []string{"core", "main", "event1"},
  401. nil,
  402. }, m)
  403. // Finish the processor
  404. proc.Finish()
  405. // Now both rules should trigger
  406. if log.String() != `TestRule1
  407. TestRule2
  408. ` {
  409. t.Error("Unexpected result:", log.String())
  410. return
  411. }
  412. }
  413. func TestProcessorStateMatching(t *testing.T) {
  414. UnitTestResetIDs()
  415. var logLock = sync.Mutex{}
  416. var log bytes.Buffer
  417. proc := NewProcessor(10)
  418. if res := proc.Workers(); res != 10 {
  419. t.Error("Unexpected number of workers:", res)
  420. return
  421. }
  422. // Add rules to the processor
  423. rule1 := &Rule{
  424. "TestRule1", // Name
  425. "", // Description
  426. []string{"core.main.*"}, // Kind match
  427. []string{"data"}, // Match on event cascade scope
  428. map[string]interface{}{"name": nil, "test": 1}, // Simple state match
  429. 0, // Priority of the rule
  430. nil, // List of suppressed rules by this rule
  431. func(p Processor, m Monitor, e *Event, tid uint64) error { // Action of the rule
  432. logLock.Lock()
  433. log.WriteString("TestRule1\n")
  434. logLock.Unlock()
  435. time.Sleep(2 * time.Millisecond)
  436. return nil
  437. },
  438. }
  439. rule2 := &Rule{
  440. "TestRule2", // Name
  441. "", // Description
  442. []string{"core.main.*"}, // Kind match
  443. []string{"data"}, // Match on event cascade scope
  444. map[string]interface{}{"name": nil, "test": "123"}, // Simple state match
  445. 0, // Priority of the rule
  446. nil, // List of suppressed rules by this rule
  447. func(p Processor, m Monitor, e *Event, tid uint64) error { // Action of the rule
  448. logLock.Lock()
  449. log.WriteString("TestRule2\n")
  450. logLock.Unlock()
  451. time.Sleep(2 * time.Millisecond)
  452. return nil
  453. },
  454. }
  455. proc.AddRule(rule1)
  456. proc.AddRule(rule2)
  457. proc.Start()
  458. // Push a root event
  459. proc.AddEvent(&Event{
  460. "InitialEvent",
  461. []string{"core", "main", "event1"},
  462. map[interface{}]interface{}{"name": "foo", "test": "123"},
  463. }, nil)
  464. proc.Finish()
  465. if log.String() != `TestRule2
  466. ` {
  467. t.Error("Unexpected result:", log.String())
  468. return
  469. }
  470. proc.Start()
  471. proc.AddEvent(&Event{
  472. "InitialEvent",
  473. []string{"core", "main", "event1"},
  474. map[interface{}]interface{}{"name": nil, "test": 1, "foobar": 123},
  475. }, nil)
  476. proc.AddEvent(&Event{
  477. "InitialEvent",
  478. []string{"core", "main", "event1"},
  479. map[interface{}]interface{}{"name": "bar", "test": 1},
  480. }, nil)
  481. // The following rule should not trigger as it is missing name
  482. proc.AddEvent(&Event{
  483. "InitialEvent",
  484. []string{"core", "main", "event1"},
  485. map[interface{}]interface{}{"foobar": nil, "test": "123"},
  486. }, nil)
  487. proc.Finish()
  488. if log.String() != `TestRule2
  489. TestRule1
  490. TestRule1
  491. ` {
  492. t.Error("Unexpected result:", log.String())
  493. return
  494. }
  495. }
  496. func TestProcessorSimpleErrorHandling(t *testing.T) {
  497. UnitTestResetIDs()
  498. proc := NewProcessor(10)
  499. if proc.ThreadPool() == nil {
  500. t.Error("Should have a thread pool")
  501. return
  502. }
  503. // Add rules to the processor
  504. rule1 := &Rule{
  505. "TestRule1", // Name
  506. "", // Description
  507. []string{"core.main.event1"}, // Kind match
  508. []string{"data"}, // Match on event cascade scope
  509. nil,
  510. 0, // Priority of the rule
  511. nil, // List of suppressed rules by this rule
  512. func(p Processor, m Monitor, e *Event, tid uint64) error { // Action of the rule
  513. p.AddEvent(&Event{
  514. "event2",
  515. []string{"core", "main", "event2"},
  516. nil,
  517. }, m.NewChildMonitor(1))
  518. return errors.New("testerror")
  519. },
  520. }
  521. rule2 := &Rule{
  522. "TestRule2", // Name
  523. "", // Description
  524. []string{"core.main.event2"}, // Kind match
  525. []string{"data"}, // Match on event cascade scope
  526. nil,
  527. 0, // Priority of the rule
  528. nil, // List of suppressed rules by this rule
  529. func(p Processor, m Monitor, e *Event, tid uint64) error { // Action of the rule
  530. p.AddEvent(&Event{
  531. "event3",
  532. []string{"core", "main", "event3"},
  533. nil,
  534. }, m.NewChildMonitor(1))
  535. return nil
  536. },
  537. }
  538. rule3 := &Rule{
  539. "TestRule3", // Name
  540. "", // Description
  541. []string{"core.main.event3", "core.main.event1"}, // Kind match
  542. []string{"data"}, // Match on event cascade scope
  543. nil,
  544. 0, // Priority of the rule
  545. nil, // List of suppressed rules by this rule
  546. func(p Processor, m Monitor, e *Event, tid uint64) error { // Action of the rule
  547. return errors.New("testerror2")
  548. },
  549. }
  550. // Add rule 1 twice
  551. proc.AddRule(rule1)
  552. proc.AddRule(rule1.CopyAs("TestRule1Copy"))
  553. proc.AddRule(rule2)
  554. proc.AddRule(rule3)
  555. recordedErrors := 0
  556. proc.SetRootMonitorErrorObserver(func(rm *RootMonitor) {
  557. recordedErrors = len(rm.AllErrors()[0].ErrorMap)
  558. })
  559. // First test will always execute all rules and collect all errors
  560. proc.SetFailOnFirstErrorInTriggerSequence(false)
  561. proc.Start()
  562. // Push a root event
  563. mon, err := proc.AddEventAndWait(&Event{
  564. "InitialEvent",
  565. []string{"core", "main", "event1"},
  566. map[interface{}]interface{}{"name": "foo", "test": "123"},
  567. }, nil)
  568. rmon, ok := mon.(*RootMonitor)
  569. if !ok {
  570. t.Error("Root monitor expected:", mon, err)
  571. return
  572. }
  573. proc.Finish()
  574. if fmt.Sprint(mon) != "Monitor 1 (parent: <nil> priority: 0 activated: true finished: true)" {
  575. t.Error("Unexpected result:", mon)
  576. return
  577. }
  578. _, err = proc.AddEvent(&Event{}, nil)
  579. if err.Error() != "Cannot add event if the processor is stopping or not running" {
  580. t.Error("Unexpected error", err)
  581. return
  582. }
  583. // Two errors should have been collected
  584. errs := rmon.AllErrors()
  585. if len(errs) != 3 {
  586. t.Error("Unexpected number of errors:", len(errs))
  587. return
  588. }
  589. if recordedErrors != 3 {
  590. t.Error("Unexpected number of recorded errors:", recordedErrors)
  591. return
  592. }
  593. if fmt.Sprint(errs) != `[Taskerrors:
  594. InitialEvent -> TestRule1 : testerror
  595. InitialEvent -> TestRule1Copy : testerror
  596. InitialEvent -> TestRule3 : testerror2 Taskerror:
  597. InitialEvent -> event2 -> event3 -> TestRule3 : testerror2 Taskerror:
  598. InitialEvent -> event2 -> event3 -> TestRule3 : testerror2]` {
  599. t.Error("Unexpected errors:", errs)
  600. return
  601. }
  602. testProcessorAdvancedErrorHandling(t, proc, &recordedErrors)
  603. }
  604. func testProcessorAdvancedErrorHandling(t *testing.T, proc Processor, recordedErrorsPtr *int) {
  605. // Second test will fail on the first failed rule in an event trigger sequence
  606. proc.SetFailOnFirstErrorInTriggerSequence(true)
  607. proc.Start()
  608. mon, err := proc.AddEventAndWait(&Event{
  609. "InitialEvent",
  610. []string{"core", "main", "event1"},
  611. map[interface{}]interface{}{"name": "foo", "test": "123"},
  612. }, nil)
  613. rmon, ok := mon.(*RootMonitor)
  614. if !ok {
  615. t.Error("Root monitor expected:", mon, err)
  616. return
  617. }
  618. proc.Finish()
  619. errs := rmon.AllErrors()
  620. if len(errs) != 2 {
  621. t.Error("Unexpected number of errors:", len(errs))
  622. return
  623. }
  624. if fmt.Sprint(errs) != `[Taskerror:
  625. InitialEvent -> TestRule1 : testerror Taskerror:
  626. InitialEvent -> event2 -> event3 -> TestRule3 : testerror2]` {
  627. t.Error("Unexpected errors:", errs)
  628. return
  629. }
  630. if *recordedErrorsPtr != 1 {
  631. t.Error("Unexpected number of recorded errors:", *recordedErrorsPtr)
  632. return
  633. }
  634. // Now test AddEventAndWait
  635. proc.SetFailOnFirstErrorInTriggerSequence(false)
  636. proc.Start()
  637. mon, err = proc.AddEventAndWait(&Event{
  638. "InitialEvent1",
  639. []string{"core", "main", "event5"},
  640. map[interface{}]interface{}{"name": "foo", "test": "123"},
  641. }, nil)
  642. if mon != nil || err != nil {
  643. t.Error("Nothing should have triggered: ", err)
  644. return
  645. }
  646. // Push a root event
  647. mon, err = proc.AddEventAndWait(&Event{
  648. "InitialEvent",
  649. []string{"core", "main", "event1"},
  650. map[interface{}]interface{}{"name": "foo", "test": "123"},
  651. }, nil)
  652. rmon, ok = mon.(*RootMonitor)
  653. if !ok {
  654. t.Error("Root monitor expected:", mon, err)
  655. return
  656. }
  657. if fmt.Sprint(mon) != "Monitor 10 (parent: <nil> priority: 0 activated: true finished: true)" {
  658. t.Error("Unexpected result:", mon)
  659. return
  660. }
  661. if proc.Stopped() {
  662. t.Error("Processor should not be stopped at this point")
  663. return
  664. }
  665. errs = rmon.AllErrors()
  666. if len(errs) != 3 {
  667. t.Error("Unexpected number of errors:", len(errs))
  668. return
  669. }
  670. if *recordedErrorsPtr != 3 {
  671. t.Error("Unexpected number of recorded errors:", *recordedErrorsPtr)
  672. return
  673. }
  674. if fmt.Sprint(errs) != `[Taskerrors:
  675. InitialEvent -> TestRule1 : testerror
  676. InitialEvent -> TestRule1Copy : testerror
  677. InitialEvent -> TestRule3 : testerror2 Taskerror:
  678. InitialEvent -> event2 -> event3 -> TestRule3 : testerror2 Taskerror:
  679. InitialEvent -> event2 -> event3 -> TestRule3 : testerror2]` {
  680. t.Error("Unexpected errors:", errs)
  681. return
  682. }
  683. proc.Finish()
  684. }