funcs_analytic_test.go 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582
  1. // Copyright 2022-2023 EMQ Technologies Co., Ltd.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package function
  15. import (
  16. "errors"
  17. "fmt"
  18. "reflect"
  19. "testing"
  20. "github.com/stretchr/testify/assert"
  21. "github.com/stretchr/testify/require"
  22. "github.com/lf-edge/ekuiper/internal/conf"
  23. kctx "github.com/lf-edge/ekuiper/internal/topo/context"
  24. "github.com/lf-edge/ekuiper/internal/topo/state"
  25. "github.com/lf-edge/ekuiper/pkg/api"
  26. "github.com/lf-edge/ekuiper/pkg/ast"
  27. )
  28. func TestChangedColValidation(t *testing.T) {
  29. f, ok := builtins["changed_col"]
  30. if !ok {
  31. t.Fatal("builtin not found")
  32. }
  33. tests := []struct {
  34. args []ast.Expr
  35. err error
  36. }{
  37. {
  38. args: []ast.Expr{
  39. &ast.StringLiteral{Val: "foo"},
  40. },
  41. err: fmt.Errorf("Expect 2 arguments but found 1."),
  42. }, {
  43. args: []ast.Expr{
  44. &ast.StringLiteral{Val: "foo"},
  45. &ast.StringLiteral{Val: "bar"},
  46. },
  47. err: fmt.Errorf("Expect boolean type for parameter 1"),
  48. }, {
  49. args: []ast.Expr{
  50. &ast.StringLiteral{Val: "foo"},
  51. &ast.StringLiteral{Val: "bar"},
  52. &ast.StringLiteral{Val: "baz"},
  53. },
  54. err: fmt.Errorf("Expect 2 arguments but found 3."),
  55. }, {
  56. args: []ast.Expr{
  57. &ast.BooleanLiteral{Val: true},
  58. &ast.StringLiteral{Val: "baz"},
  59. },
  60. },
  61. }
  62. for i, tt := range tests {
  63. err := f.val(nil, tt.args)
  64. if !reflect.DeepEqual(err, tt.err) {
  65. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, err, tt.err)
  66. }
  67. }
  68. }
  69. func TestChangedColExec(t *testing.T) {
  70. f, ok := builtins["changed_col"]
  71. if !ok {
  72. t.Fatal("builtin not found")
  73. }
  74. contextLogger := conf.Log.WithField("rule", "testExec")
  75. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  76. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  77. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  78. tests := []struct {
  79. args []interface{}
  80. result interface{}
  81. }{
  82. { // 1
  83. args: []interface{}{
  84. true,
  85. "bar",
  86. true,
  87. "self",
  88. },
  89. result: "bar",
  90. }, { // 2
  91. args: []interface{}{
  92. true,
  93. "bar",
  94. true,
  95. "self",
  96. },
  97. result: nil,
  98. }, { // 3
  99. args: []interface{}{
  100. true,
  101. "baz",
  102. true,
  103. "self",
  104. },
  105. result: "baz",
  106. }, { // 4
  107. args: []interface{}{
  108. false,
  109. nil,
  110. true,
  111. "self",
  112. },
  113. result: nil,
  114. }, { // 5
  115. args: []interface{}{
  116. false,
  117. "baz",
  118. true,
  119. "self",
  120. },
  121. result: "baz",
  122. }, { // 6
  123. args: []interface{}{
  124. true,
  125. "foo",
  126. true,
  127. "self",
  128. },
  129. result: "foo",
  130. },
  131. }
  132. for i, tt := range tests {
  133. result, _ := f.exec(fctx, tt.args)
  134. if !reflect.DeepEqual(result, tt.result) {
  135. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  136. }
  137. }
  138. }
  139. func TestChangedColPartition(t *testing.T) {
  140. f, ok := builtins["changed_col"]
  141. if !ok {
  142. t.Fatal("builtin not found")
  143. }
  144. contextLogger := conf.Log.WithField("rule", "testExec")
  145. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  146. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  147. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  148. tests := []struct {
  149. args []interface{}
  150. result interface{}
  151. }{
  152. { // 1
  153. args: []interface{}{
  154. true,
  155. "bar",
  156. true,
  157. "2",
  158. },
  159. result: "bar",
  160. }, { // 2
  161. args: []interface{}{
  162. true,
  163. "bar",
  164. true,
  165. "1",
  166. },
  167. result: "bar",
  168. }, { // 3
  169. args: []interface{}{
  170. true,
  171. "baz",
  172. true,
  173. "2",
  174. },
  175. result: "baz",
  176. }, { // 4
  177. args: []interface{}{
  178. false,
  179. nil,
  180. true,
  181. "1",
  182. },
  183. result: nil,
  184. }, { // 5
  185. args: []interface{}{
  186. false,
  187. "baz",
  188. true,
  189. "2",
  190. },
  191. result: nil,
  192. }, { // 6
  193. args: []interface{}{
  194. true,
  195. "foo",
  196. true,
  197. "1",
  198. },
  199. result: "foo",
  200. },
  201. }
  202. for i, tt := range tests {
  203. result, _ := f.exec(fctx, tt.args)
  204. if !reflect.DeepEqual(result, tt.result) {
  205. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  206. }
  207. }
  208. }
  209. func TestChangedColPartitionWithWhen(t *testing.T) {
  210. f, ok := builtins["changed_col"]
  211. if !ok {
  212. t.Fatal("builtin not found")
  213. }
  214. contextLogger := conf.Log.WithField("rule", "testExec")
  215. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  216. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  217. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  218. tests := []struct {
  219. args []interface{}
  220. result interface{}
  221. }{
  222. { // 1
  223. args: []interface{}{
  224. true,
  225. "bar",
  226. true,
  227. "2",
  228. },
  229. result: "bar",
  230. }, { // 2
  231. args: []interface{}{
  232. true,
  233. "bar",
  234. true,
  235. "1",
  236. },
  237. result: "bar",
  238. }, { // 3
  239. args: []interface{}{
  240. true,
  241. "baz",
  242. true,
  243. "2",
  244. },
  245. result: "baz",
  246. }, { // 3.1 copy of 3 with baz changed to bar and when condition false
  247. args: []interface{}{
  248. true,
  249. "bar",
  250. false,
  251. "2",
  252. },
  253. result: nil,
  254. }, { // 4
  255. args: []interface{}{
  256. false,
  257. nil,
  258. true,
  259. "1",
  260. },
  261. result: nil,
  262. }, { // 5
  263. args: []interface{}{
  264. false,
  265. "baz",
  266. true,
  267. "2",
  268. },
  269. result: nil,
  270. }, { // 6
  271. args: []interface{}{
  272. true,
  273. "foo",
  274. true,
  275. "1",
  276. },
  277. result: "foo",
  278. }, { // 7
  279. args: []interface{}{
  280. true,
  281. "bar",
  282. false,
  283. "1",
  284. },
  285. result: nil,
  286. },
  287. }
  288. for i, tt := range tests {
  289. result, _ := f.exec(fctx, tt.args)
  290. if !reflect.DeepEqual(result, tt.result) {
  291. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  292. }
  293. }
  294. }
  295. func TestHadChangedValidation(t *testing.T) {
  296. f, ok := builtins["had_changed"]
  297. if !ok {
  298. t.Fatal("builtin not found")
  299. }
  300. tests := []struct {
  301. args []ast.Expr
  302. err error
  303. }{
  304. {
  305. args: []ast.Expr{
  306. &ast.StringLiteral{Val: "foo"},
  307. },
  308. err: fmt.Errorf("expect more than one arg but got 1"),
  309. }, {
  310. args: []ast.Expr{
  311. &ast.StringLiteral{Val: "foo"},
  312. &ast.StringLiteral{Val: "bar"},
  313. &ast.StringLiteral{Val: "baz"},
  314. },
  315. err: fmt.Errorf("Expect bool type for parameter 1"),
  316. }, {
  317. args: []ast.Expr{
  318. &ast.IntegerLiteral{Val: 20},
  319. &ast.BooleanLiteral{Val: true},
  320. &ast.StringLiteral{Val: "baz"},
  321. },
  322. err: fmt.Errorf("Expect bool type for parameter 1"),
  323. }, {
  324. args: []ast.Expr{
  325. &ast.FieldRef{
  326. StreamName: "demo",
  327. Name: "a",
  328. AliasRef: nil,
  329. },
  330. &ast.BooleanLiteral{Val: true},
  331. &ast.StringLiteral{Val: "baz"},
  332. },
  333. err: nil,
  334. },
  335. }
  336. for i, tt := range tests {
  337. err := f.val(nil, tt.args)
  338. if !reflect.DeepEqual(err, tt.err) {
  339. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, err, tt.err)
  340. }
  341. }
  342. }
  343. func TestHadChangedExec(t *testing.T) {
  344. f, ok := builtins["had_changed"]
  345. if !ok {
  346. t.Fatal("builtin not found")
  347. }
  348. contextLogger := conf.Log.WithField("rule", "testExec")
  349. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  350. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  351. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 1)
  352. tests := []struct {
  353. args []interface{}
  354. result interface{}
  355. }{
  356. { // 0
  357. args: []interface{}{
  358. "foo",
  359. "bar",
  360. "baz",
  361. true,
  362. "self",
  363. },
  364. result: fmt.Errorf("first arg is not a bool but got foo"),
  365. }, { // 1
  366. args: []interface{}{
  367. "foo",
  368. "bar",
  369. true,
  370. "self",
  371. },
  372. result: fmt.Errorf("first arg is not a bool but got foo"),
  373. }, { // 2
  374. args: []interface{}{
  375. true,
  376. "bar",
  377. 20,
  378. true,
  379. "self",
  380. },
  381. result: true,
  382. }, { // 3
  383. args: []interface{}{
  384. true,
  385. "baz",
  386. 44,
  387. true,
  388. "self",
  389. },
  390. result: true,
  391. }, { // 4
  392. args: []interface{}{
  393. true,
  394. "baz",
  395. 44,
  396. true,
  397. "self",
  398. },
  399. result: false,
  400. }, { // 5
  401. args: []interface{}{
  402. true,
  403. "foo",
  404. 44,
  405. true,
  406. "self",
  407. },
  408. result: true,
  409. }, { // 6
  410. args: []interface{}{
  411. true,
  412. "foo",
  413. nil,
  414. true,
  415. "self",
  416. },
  417. result: false,
  418. }, { // 7
  419. args: []interface{}{
  420. true,
  421. "foo",
  422. 44,
  423. true,
  424. "self",
  425. },
  426. result: false,
  427. }, { // 8
  428. args: []interface{}{
  429. true,
  430. "baz",
  431. 44,
  432. true,
  433. "self",
  434. },
  435. result: true,
  436. },
  437. }
  438. for i, tt := range tests {
  439. result, _ := f.exec(fctx, tt.args)
  440. if !reflect.DeepEqual(result, tt.result) {
  441. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  442. }
  443. }
  444. }
  445. func TestHadChangedExecAllowNull(t *testing.T) {
  446. f, ok := builtins["had_changed"]
  447. if !ok {
  448. t.Fatal("builtin not found")
  449. }
  450. contextLogger := conf.Log.WithField("rule", "testExec")
  451. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  452. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  453. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 1)
  454. tests := []struct {
  455. args []interface{}
  456. result interface{}
  457. }{
  458. { // 0
  459. args: []interface{}{
  460. "foo",
  461. "bar",
  462. "baz",
  463. true,
  464. "self",
  465. },
  466. result: fmt.Errorf("first arg is not a bool but got foo"),
  467. }, { // 1
  468. args: []interface{}{
  469. "foo",
  470. "bar",
  471. true,
  472. "self",
  473. },
  474. result: fmt.Errorf("first arg is not a bool but got foo"),
  475. }, { // 2
  476. args: []interface{}{
  477. false,
  478. "bar",
  479. 20,
  480. true,
  481. "self",
  482. },
  483. result: true,
  484. }, { // 3
  485. args: []interface{}{
  486. false,
  487. "baz",
  488. nil,
  489. true,
  490. "self",
  491. },
  492. result: true,
  493. }, { // 4
  494. args: []interface{}{
  495. false,
  496. "baz",
  497. 44,
  498. true,
  499. "self",
  500. },
  501. result: true,
  502. }, { // 5
  503. args: []interface{}{
  504. false,
  505. nil,
  506. 44,
  507. true,
  508. "self",
  509. },
  510. result: true,
  511. }, { // 6
  512. args: []interface{}{
  513. false,
  514. "baz",
  515. 44,
  516. true,
  517. "self",
  518. },
  519. result: true,
  520. }, { // 7
  521. args: []interface{}{
  522. false,
  523. "baz",
  524. 44,
  525. true,
  526. "self",
  527. },
  528. result: false,
  529. }, { // 8
  530. args: []interface{}{
  531. false,
  532. nil,
  533. nil,
  534. true,
  535. "self",
  536. },
  537. result: true,
  538. }, { // 9
  539. args: []interface{}{
  540. false,
  541. "baz",
  542. 44,
  543. true,
  544. "self",
  545. },
  546. result: true,
  547. },
  548. }
  549. for i, tt := range tests {
  550. result, _ := f.exec(fctx, tt.args)
  551. if !reflect.DeepEqual(result, tt.result) {
  552. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  553. }
  554. }
  555. }
  556. func TestHadChangedPartition(t *testing.T) {
  557. f, ok := builtins["had_changed"]
  558. if !ok {
  559. t.Fatal("builtin not found")
  560. }
  561. contextLogger := conf.Log.WithField("rule", "testExec")
  562. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  563. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  564. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 1)
  565. tests := []struct {
  566. args []interface{}
  567. result interface{}
  568. }{
  569. { // 0
  570. args: []interface{}{
  571. "foo",
  572. "bar",
  573. "baz",
  574. true,
  575. "1",
  576. },
  577. result: fmt.Errorf("first arg is not a bool but got foo"),
  578. }, { // 1
  579. args: []interface{}{
  580. "foo",
  581. "bar",
  582. true,
  583. "1",
  584. },
  585. result: fmt.Errorf("first arg is not a bool but got foo"),
  586. }, { // 2
  587. args: []interface{}{
  588. true,
  589. "bar",
  590. 20,
  591. true,
  592. "3",
  593. },
  594. result: true,
  595. }, { // 3
  596. args: []interface{}{
  597. true,
  598. "baz",
  599. 44,
  600. true,
  601. "2",
  602. },
  603. result: true,
  604. }, { // 4
  605. args: []interface{}{
  606. true,
  607. "baz",
  608. 44,
  609. true,
  610. "2",
  611. },
  612. result: false,
  613. }, { // 5
  614. args: []interface{}{
  615. true,
  616. "foo",
  617. 44,
  618. true,
  619. "3",
  620. },
  621. result: true,
  622. }, { // 6
  623. args: []interface{}{
  624. true,
  625. "foo",
  626. nil,
  627. true,
  628. "1",
  629. },
  630. result: true,
  631. }, { // 7
  632. args: []interface{}{
  633. true,
  634. "foo",
  635. 44,
  636. true,
  637. "2",
  638. },
  639. result: true,
  640. }, { // 8
  641. args: []interface{}{
  642. true,
  643. "baz",
  644. 44,
  645. true,
  646. "3",
  647. },
  648. result: true,
  649. },
  650. }
  651. for i, tt := range tests {
  652. result, _ := f.exec(fctx, tt.args)
  653. if !reflect.DeepEqual(result, tt.result) {
  654. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  655. }
  656. }
  657. }
  658. func TestHadChangedPartitionWithWhen(t *testing.T) {
  659. f, ok := builtins["had_changed"]
  660. if !ok {
  661. t.Fatal("builtin not found")
  662. }
  663. contextLogger := conf.Log.WithField("rule", "testExec")
  664. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  665. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  666. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 1)
  667. tests := []struct {
  668. args []interface{}
  669. result interface{}
  670. }{
  671. { // 0
  672. args: []interface{}{
  673. "foo",
  674. "bar",
  675. "baz",
  676. true,
  677. "1",
  678. },
  679. result: fmt.Errorf("first arg is not a bool but got foo"),
  680. }, { // 1
  681. args: []interface{}{
  682. "foo",
  683. "bar",
  684. true,
  685. "1",
  686. },
  687. result: fmt.Errorf("first arg is not a bool but got foo"),
  688. }, { // 2
  689. args: []interface{}{
  690. true,
  691. "bar",
  692. 20,
  693. true,
  694. "3",
  695. },
  696. result: true,
  697. }, { // 3
  698. args: []interface{}{
  699. true,
  700. "baz",
  701. 44,
  702. true,
  703. "2",
  704. },
  705. result: true,
  706. }, { // 4
  707. args: []interface{}{
  708. true,
  709. "baz",
  710. 44,
  711. true,
  712. "2",
  713. },
  714. result: false,
  715. }, { // 5
  716. args: []interface{}{
  717. true,
  718. "baz",
  719. 44,
  720. true,
  721. "2",
  722. },
  723. result: false,
  724. }, { // 6
  725. args: []interface{}{
  726. true,
  727. "foo",
  728. 45,
  729. false,
  730. "2",
  731. },
  732. result: false,
  733. }, { // 7
  734. args: []interface{}{
  735. true,
  736. "foo",
  737. nil,
  738. true,
  739. "1",
  740. },
  741. result: true,
  742. }, { // 8
  743. args: []interface{}{
  744. true,
  745. "foo",
  746. 44,
  747. true,
  748. "2",
  749. },
  750. result: true,
  751. }, { // 9
  752. args: []interface{}{
  753. true,
  754. "baz",
  755. 44,
  756. false,
  757. "3",
  758. },
  759. result: false,
  760. },
  761. }
  762. for i, tt := range tests {
  763. result, _ := f.exec(fctx, tt.args)
  764. if !reflect.DeepEqual(result, tt.result) {
  765. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  766. }
  767. }
  768. }
  769. func TestLagValidation(t *testing.T) {
  770. f, ok := builtins["lag"]
  771. if !ok {
  772. t.Fatal("builtin not found")
  773. }
  774. tests := []struct {
  775. args []ast.Expr
  776. err error
  777. }{
  778. {
  779. args: []ast.Expr{
  780. &ast.StringLiteral{Val: "foo"},
  781. },
  782. err: nil,
  783. }, {
  784. args: []ast.Expr{
  785. &ast.StringLiteral{Val: "foo"},
  786. &ast.StringLiteral{Val: "bar"},
  787. },
  788. err: fmt.Errorf("Expect int type for parameter 2"),
  789. }, {
  790. args: []ast.Expr{
  791. &ast.StringLiteral{Val: "foo"},
  792. &ast.StringLiteral{Val: "bar"},
  793. &ast.StringLiteral{Val: "baz"},
  794. },
  795. err: fmt.Errorf("Expect int type for parameter 2"),
  796. }, {
  797. args: []ast.Expr{
  798. &ast.BooleanLiteral{Val: true},
  799. &ast.IntegerLiteral{Val: 23},
  800. &ast.StringLiteral{Val: "baz"},
  801. &ast.StringLiteral{Val: "baz"},
  802. },
  803. err: fmt.Errorf("Expect bool type for parameter 4"),
  804. },
  805. }
  806. for i, tt := range tests {
  807. err := f.val(nil, tt.args)
  808. if !reflect.DeepEqual(err, tt.err) {
  809. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, err, tt.err)
  810. }
  811. }
  812. }
  813. func TestLagExec(t *testing.T) {
  814. f, ok := builtins["lag"]
  815. if !ok {
  816. t.Fatal("builtin not found")
  817. }
  818. contextLogger := conf.Log.WithField("rule", "testExec")
  819. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  820. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  821. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  822. tests := []struct {
  823. args []interface{}
  824. result interface{}
  825. }{
  826. { // 1
  827. args: []interface{}{
  828. "foo",
  829. 1,
  830. "default",
  831. true,
  832. true,
  833. "self",
  834. },
  835. result: nil,
  836. },
  837. { // 2
  838. args: []interface{}{
  839. nil,
  840. 1,
  841. "default",
  842. true,
  843. true,
  844. "self",
  845. },
  846. result: "foo",
  847. },
  848. { // 3
  849. args: []interface{}{
  850. "bar",
  851. 1,
  852. "default",
  853. true,
  854. true,
  855. "self",
  856. },
  857. result: "foo",
  858. },
  859. { // 4
  860. args: []interface{}{
  861. "foo",
  862. 1,
  863. "default",
  864. true,
  865. true,
  866. "self",
  867. },
  868. result: "bar",
  869. },
  870. { // 4
  871. args: []interface{}{
  872. "foo",
  873. 1,
  874. "default",
  875. true,
  876. true,
  877. "self",
  878. },
  879. result: "foo",
  880. },
  881. { // 5
  882. args: []interface{}{
  883. "foo",
  884. 1,
  885. "default",
  886. 23,
  887. true,
  888. "self",
  889. },
  890. result: errors.New("The fourth arg is not a bool but got foo"),
  891. },
  892. }
  893. for i, tt := range tests {
  894. t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
  895. result, _ := f.exec(fctx, tt.args)
  896. assert.Equal(t, tt.result, result)
  897. })
  898. }
  899. }
  900. func TestLagPartition(t *testing.T) {
  901. f, ok := builtins["lag"]
  902. if !ok {
  903. t.Fatal("builtin not found")
  904. }
  905. contextLogger := conf.Log.WithField("rule", "testExec")
  906. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  907. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  908. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  909. tests := []struct {
  910. args []interface{}
  911. result interface{}
  912. }{
  913. { // 1
  914. args: []interface{}{
  915. "foo",
  916. true,
  917. "1",
  918. },
  919. result: nil,
  920. },
  921. { // 2
  922. args: []interface{}{
  923. "bar",
  924. true,
  925. "1",
  926. },
  927. result: "foo",
  928. },
  929. { // 3
  930. args: []interface{}{
  931. "bar",
  932. true,
  933. "2",
  934. },
  935. result: nil,
  936. },
  937. { // 4
  938. args: []interface{}{
  939. "foo",
  940. true,
  941. "1",
  942. },
  943. result: "bar",
  944. },
  945. { // 4
  946. args: []interface{}{
  947. "foo",
  948. true,
  949. "2",
  950. },
  951. result: "bar",
  952. },
  953. }
  954. for i, tt := range tests {
  955. result, _ := f.exec(fctx, tt.args)
  956. if !reflect.DeepEqual(result, tt.result) {
  957. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  958. }
  959. }
  960. }
  961. func TestLagExecWithWhen(t *testing.T) {
  962. f, ok := builtins["lag"]
  963. if !ok {
  964. t.Fatal("builtin not found")
  965. }
  966. contextLogger := conf.Log.WithField("rule", "testExec")
  967. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  968. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  969. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  970. tests := []struct {
  971. args []interface{}
  972. result interface{}
  973. }{
  974. { // 1
  975. args: []interface{}{
  976. "foo",
  977. true,
  978. "self",
  979. },
  980. result: nil,
  981. },
  982. { // 2
  983. args: []interface{}{
  984. "bar",
  985. false,
  986. "self",
  987. },
  988. result: "foo",
  989. },
  990. { // 3
  991. args: []interface{}{
  992. "bar",
  993. true,
  994. "self",
  995. },
  996. result: "foo",
  997. },
  998. { // 4
  999. args: []interface{}{
  1000. "foo",
  1001. false,
  1002. "self",
  1003. },
  1004. result: "bar",
  1005. },
  1006. { // 4
  1007. args: []interface{}{
  1008. "foo",
  1009. true,
  1010. "self",
  1011. },
  1012. result: "bar",
  1013. },
  1014. }
  1015. for i, tt := range tests {
  1016. result, _ := f.exec(fctx, tt.args)
  1017. if !reflect.DeepEqual(result, tt.result) {
  1018. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  1019. }
  1020. }
  1021. }
  1022. func TestLagPartitionWithWhen(t *testing.T) {
  1023. f, ok := builtins["lag"]
  1024. if !ok {
  1025. t.Fatal("builtin not found")
  1026. }
  1027. contextLogger := conf.Log.WithField("rule", "testExec")
  1028. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  1029. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  1030. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  1031. tests := []struct {
  1032. args []interface{}
  1033. result interface{}
  1034. }{
  1035. { // 1
  1036. args: []interface{}{
  1037. "foo",
  1038. true,
  1039. "1",
  1040. },
  1041. result: nil,
  1042. },
  1043. { // 2
  1044. args: []interface{}{
  1045. "bar",
  1046. false,
  1047. "1",
  1048. },
  1049. result: "foo",
  1050. },
  1051. { // 3
  1052. args: []interface{}{
  1053. "bar",
  1054. true,
  1055. "2",
  1056. },
  1057. result: nil,
  1058. },
  1059. { // 4
  1060. args: []interface{}{
  1061. "foo",
  1062. true,
  1063. "1",
  1064. },
  1065. result: "foo",
  1066. },
  1067. { // 4
  1068. args: []interface{}{
  1069. "foo",
  1070. true,
  1071. "2",
  1072. },
  1073. result: "bar",
  1074. },
  1075. }
  1076. for i, tt := range tests {
  1077. result, _ := f.exec(fctx, tt.args)
  1078. if !reflect.DeepEqual(result, tt.result) {
  1079. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  1080. }
  1081. }
  1082. }
  1083. func TestLagExecIndexWithDefaultValue(t *testing.T) {
  1084. f, ok := builtins["lag"]
  1085. if !ok {
  1086. t.Fatal("builtin not found")
  1087. }
  1088. contextLogger := conf.Log.WithField("rule", "testExec")
  1089. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  1090. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  1091. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  1092. tests := []struct {
  1093. args []interface{}
  1094. result interface{}
  1095. }{
  1096. { // 1
  1097. args: []interface{}{
  1098. "bar",
  1099. 2,
  1100. "no result",
  1101. true,
  1102. "self",
  1103. },
  1104. result: "no result",
  1105. },
  1106. { // 2
  1107. args: []interface{}{
  1108. "bar",
  1109. 2,
  1110. "no result",
  1111. true,
  1112. "self",
  1113. },
  1114. result: "no result",
  1115. },
  1116. { // 3
  1117. args: []interface{}{
  1118. "foo",
  1119. 2,
  1120. "no result",
  1121. true,
  1122. "self",
  1123. },
  1124. result: "bar",
  1125. },
  1126. { // 4
  1127. args: []interface{}{
  1128. "foo",
  1129. 2,
  1130. "no result",
  1131. true,
  1132. "self",
  1133. },
  1134. result: "bar",
  1135. },
  1136. { // 4
  1137. args: []interface{}{
  1138. "foo",
  1139. 2,
  1140. "no result",
  1141. true,
  1142. "self",
  1143. },
  1144. result: "foo",
  1145. },
  1146. }
  1147. for i, tt := range tests {
  1148. result, _ := f.exec(fctx, tt.args)
  1149. if !reflect.DeepEqual(result, tt.result) {
  1150. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  1151. }
  1152. }
  1153. }
  1154. func TestLagExecIndex(t *testing.T) {
  1155. f, ok := builtins["lag"]
  1156. if !ok {
  1157. t.Fatal("builtin not found")
  1158. }
  1159. contextLogger := conf.Log.WithField("rule", "testExec")
  1160. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  1161. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  1162. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  1163. tests := []struct {
  1164. args []interface{}
  1165. result interface{}
  1166. }{
  1167. { // 1
  1168. args: []interface{}{
  1169. "bar",
  1170. 2,
  1171. true,
  1172. "self",
  1173. },
  1174. result: nil,
  1175. },
  1176. { // 2
  1177. args: []interface{}{
  1178. "bar",
  1179. 2,
  1180. true,
  1181. "self",
  1182. },
  1183. result: nil,
  1184. },
  1185. { // 3
  1186. args: []interface{}{
  1187. "foo",
  1188. 2,
  1189. true,
  1190. "self",
  1191. },
  1192. result: "bar",
  1193. },
  1194. { // 4
  1195. args: []interface{}{
  1196. "foo",
  1197. 2,
  1198. true,
  1199. "self",
  1200. },
  1201. result: "bar",
  1202. },
  1203. { // 4
  1204. args: []interface{}{
  1205. "foo",
  1206. 2,
  1207. true,
  1208. "self",
  1209. },
  1210. result: "foo",
  1211. },
  1212. }
  1213. for i, tt := range tests {
  1214. result, _ := f.exec(fctx, tt.args)
  1215. if !reflect.DeepEqual(result, tt.result) {
  1216. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  1217. }
  1218. }
  1219. }
  1220. func TestLatestExec(t *testing.T) {
  1221. f, ok := builtins["latest"]
  1222. if !ok {
  1223. t.Fatal("builtin not found")
  1224. }
  1225. contextLogger := conf.Log.WithField("rule", "testExec")
  1226. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  1227. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  1228. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  1229. tests := []struct {
  1230. args []interface{}
  1231. result interface{}
  1232. }{
  1233. { // 1
  1234. args: []interface{}{
  1235. nil,
  1236. true,
  1237. "self",
  1238. },
  1239. result: nil,
  1240. },
  1241. { // 1
  1242. args: []interface{}{
  1243. "foo",
  1244. true,
  1245. "self",
  1246. },
  1247. result: "foo",
  1248. },
  1249. { // 2
  1250. args: []interface{}{
  1251. nil,
  1252. true,
  1253. "self",
  1254. },
  1255. result: "foo",
  1256. },
  1257. { // 3
  1258. args: []interface{}{
  1259. "bar",
  1260. true,
  1261. "self",
  1262. },
  1263. result: "bar",
  1264. },
  1265. { // 4
  1266. args: []interface{}{
  1267. nil,
  1268. true,
  1269. "self",
  1270. },
  1271. result: "bar",
  1272. },
  1273. { // 4
  1274. args: []interface{}{
  1275. "foo",
  1276. true,
  1277. "self",
  1278. },
  1279. result: "foo",
  1280. },
  1281. }
  1282. for i, tt := range tests {
  1283. result, _ := f.exec(fctx, tt.args)
  1284. if !reflect.DeepEqual(result, tt.result) {
  1285. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  1286. }
  1287. }
  1288. }
  1289. func TestLatestExecWithWhen(t *testing.T) {
  1290. f, ok := builtins["latest"]
  1291. if !ok {
  1292. t.Fatal("builtin not found")
  1293. }
  1294. contextLogger := conf.Log.WithField("rule", "testExec")
  1295. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  1296. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  1297. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  1298. tests := []struct {
  1299. args []interface{}
  1300. result interface{}
  1301. }{
  1302. { // 1
  1303. args: []interface{}{
  1304. "foo",
  1305. true,
  1306. "self",
  1307. },
  1308. result: "foo",
  1309. },
  1310. { // 2
  1311. args: []interface{}{
  1312. nil,
  1313. true,
  1314. "self",
  1315. },
  1316. result: "foo",
  1317. },
  1318. { // 3
  1319. args: []interface{}{
  1320. "bar",
  1321. false,
  1322. "self",
  1323. },
  1324. result: "foo",
  1325. },
  1326. { // 4
  1327. args: []interface{}{
  1328. nil,
  1329. true,
  1330. "self",
  1331. },
  1332. result: "foo",
  1333. },
  1334. { // 4
  1335. args: []interface{}{
  1336. "foo",
  1337. true,
  1338. "self",
  1339. },
  1340. result: "foo",
  1341. },
  1342. }
  1343. for i, tt := range tests {
  1344. result, _ := f.exec(fctx, tt.args)
  1345. if !reflect.DeepEqual(result, tt.result) {
  1346. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  1347. }
  1348. }
  1349. }
  1350. func TestLatestPartition(t *testing.T) {
  1351. f, ok := builtins["latest"]
  1352. if !ok {
  1353. t.Fatal("builtin not found")
  1354. }
  1355. contextLogger := conf.Log.WithField("rule", "testExec")
  1356. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  1357. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  1358. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  1359. tests := []struct {
  1360. args []interface{}
  1361. result interface{}
  1362. }{
  1363. { // 1
  1364. args: []interface{}{
  1365. "foo",
  1366. true,
  1367. "2",
  1368. },
  1369. result: "foo",
  1370. },
  1371. { // 2
  1372. args: []interface{}{
  1373. nil,
  1374. "dd",
  1375. true,
  1376. "1",
  1377. },
  1378. result: "dd",
  1379. },
  1380. { // 3
  1381. args: []interface{}{
  1382. "bar",
  1383. true,
  1384. "1",
  1385. },
  1386. result: "bar",
  1387. },
  1388. { // 4
  1389. args: []interface{}{
  1390. nil,
  1391. true,
  1392. "2",
  1393. },
  1394. result: "foo",
  1395. },
  1396. { // 4
  1397. args: []interface{}{
  1398. "foo",
  1399. true,
  1400. "1",
  1401. },
  1402. result: "foo",
  1403. },
  1404. }
  1405. for i, tt := range tests {
  1406. result, _ := f.exec(fctx, tt.args)
  1407. if !reflect.DeepEqual(result, tt.result) {
  1408. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  1409. }
  1410. }
  1411. }
  1412. func TestAccumulateAgg(t *testing.T) {
  1413. tests := []struct {
  1414. name string
  1415. results []interface{}
  1416. testargs []interface{}
  1417. }{
  1418. {
  1419. name: "acc_count",
  1420. testargs: []interface{}{
  1421. "1",
  1422. float64(1),
  1423. float32(1),
  1424. 1,
  1425. int32(1),
  1426. int64(1),
  1427. },
  1428. results: []interface{}{
  1429. 1, 2, 3, 4, 5, 6,
  1430. },
  1431. },
  1432. {
  1433. name: "acc_avg",
  1434. testargs: []interface{}{
  1435. "1",
  1436. float64(1),
  1437. float32(1),
  1438. 1,
  1439. int32(1),
  1440. int64(1),
  1441. },
  1442. results: []interface{}{
  1443. fmt.Errorf("the value should be number"),
  1444. float64(1),
  1445. float64(1),
  1446. float64(1),
  1447. float64(1),
  1448. float64(1),
  1449. },
  1450. },
  1451. {
  1452. name: "acc_max",
  1453. testargs: []interface{}{
  1454. "1",
  1455. float64(1),
  1456. float32(2),
  1457. 3,
  1458. int32(4),
  1459. int64(5),
  1460. },
  1461. results: []interface{}{
  1462. fmt.Errorf("the value should be number"),
  1463. float64(1),
  1464. float64(2),
  1465. float64(3),
  1466. float64(4),
  1467. float64(5),
  1468. },
  1469. },
  1470. {
  1471. name: "acc_min",
  1472. testargs: []interface{}{
  1473. "1",
  1474. float64(5),
  1475. float32(4),
  1476. 3,
  1477. int32(2),
  1478. int64(1),
  1479. },
  1480. results: []interface{}{
  1481. fmt.Errorf("the value should be number"),
  1482. float64(5),
  1483. float64(4),
  1484. float64(3),
  1485. float64(2),
  1486. float64(1),
  1487. },
  1488. },
  1489. {
  1490. name: "acc_sum",
  1491. testargs: []interface{}{
  1492. "1",
  1493. float64(1),
  1494. float32(1),
  1495. 1,
  1496. int32(1),
  1497. int64(1),
  1498. },
  1499. results: []interface{}{
  1500. fmt.Errorf("the value should be number"),
  1501. float64(1),
  1502. float64(2),
  1503. float64(3),
  1504. float64(4),
  1505. float64(5),
  1506. },
  1507. },
  1508. }
  1509. for _, test := range tests {
  1510. f, ok := builtins[test.name]
  1511. require.True(t, ok)
  1512. contextLogger := conf.Log.WithField("rule", "testExec")
  1513. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  1514. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  1515. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  1516. for i, arg := range test.testargs {
  1517. result, _ := f.exec(fctx, []interface{}{arg, true, fmt.Sprintf("%s_key", test.name)})
  1518. require.Equal(t, test.results[i], result)
  1519. }
  1520. }
  1521. tests2 := []struct {
  1522. name string
  1523. result interface{}
  1524. }{
  1525. {
  1526. "acc_sum",
  1527. float64(0),
  1528. },
  1529. {
  1530. "acc_max",
  1531. 0,
  1532. },
  1533. {
  1534. "acc_min",
  1535. 0,
  1536. },
  1537. {
  1538. "acc_avg",
  1539. float64(0),
  1540. },
  1541. {
  1542. "acc_count",
  1543. 0,
  1544. },
  1545. }
  1546. for _, test := range tests2 {
  1547. f, ok := builtins[test.name]
  1548. require.True(t, ok)
  1549. contextLogger := conf.Log.WithField("rule", "testExec")
  1550. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  1551. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  1552. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  1553. result, b := f.exec(fctx, []interface{}{1, false, fmt.Sprintf("%s_key", test.name)})
  1554. require.True(t, b)
  1555. require.Equal(t, test.result, result)
  1556. }
  1557. }