funcs_analytic_test.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939
  1. // Copyright 2022 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. "fmt"
  17. "github.com/lf-edge/ekuiper/internal/conf"
  18. kctx "github.com/lf-edge/ekuiper/internal/topo/context"
  19. "github.com/lf-edge/ekuiper/internal/topo/state"
  20. "github.com/lf-edge/ekuiper/pkg/api"
  21. "github.com/lf-edge/ekuiper/pkg/ast"
  22. "reflect"
  23. "testing"
  24. )
  25. func TestChangedColValidation(t *testing.T) {
  26. f, ok := builtins["changed_col"]
  27. if !ok {
  28. t.Fatal("builtin not found")
  29. }
  30. var tests = []struct {
  31. args []ast.Expr
  32. err error
  33. }{
  34. {
  35. args: []ast.Expr{
  36. &ast.StringLiteral{Val: "foo"},
  37. },
  38. err: fmt.Errorf("Expect 2 arguments but found 1."),
  39. }, {
  40. args: []ast.Expr{
  41. &ast.StringLiteral{Val: "foo"},
  42. &ast.StringLiteral{Val: "bar"},
  43. },
  44. err: fmt.Errorf("Expect boolean type for parameter 1"),
  45. }, {
  46. args: []ast.Expr{
  47. &ast.StringLiteral{Val: "foo"},
  48. &ast.StringLiteral{Val: "bar"},
  49. &ast.StringLiteral{Val: "baz"},
  50. },
  51. err: fmt.Errorf("Expect 2 arguments but found 3."),
  52. }, {
  53. args: []ast.Expr{
  54. &ast.BooleanLiteral{Val: true},
  55. &ast.StringLiteral{Val: "baz"},
  56. },
  57. },
  58. }
  59. for i, tt := range tests {
  60. err := f.val(nil, tt.args)
  61. if !reflect.DeepEqual(err, tt.err) {
  62. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, err, tt.err)
  63. }
  64. }
  65. }
  66. func TestChangedColExec(t *testing.T) {
  67. f, ok := builtins["changed_col"]
  68. if !ok {
  69. t.Fatal("builtin not found")
  70. }
  71. contextLogger := conf.Log.WithField("rule", "testExec")
  72. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  73. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  74. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  75. var tests = []struct {
  76. args []interface{}
  77. result interface{}
  78. }{
  79. { // 0
  80. args: []interface{}{
  81. "foo",
  82. "bar",
  83. "self",
  84. },
  85. result: fmt.Errorf("first arg is not a bool but got foo"),
  86. }, { // 1
  87. args: []interface{}{
  88. true,
  89. "bar",
  90. "self",
  91. },
  92. result: "bar",
  93. }, { // 2
  94. args: []interface{}{
  95. true,
  96. "bar",
  97. "self",
  98. },
  99. result: nil,
  100. }, { // 3
  101. args: []interface{}{
  102. true,
  103. "baz",
  104. "self",
  105. },
  106. result: "baz",
  107. }, { // 4
  108. args: []interface{}{
  109. false,
  110. nil,
  111. "self",
  112. },
  113. result: nil,
  114. }, { // 5
  115. args: []interface{}{
  116. false,
  117. "baz",
  118. "self",
  119. },
  120. result: "baz",
  121. }, { // 6
  122. args: []interface{}{
  123. true,
  124. "foo",
  125. "self",
  126. },
  127. result: "foo",
  128. },
  129. }
  130. for i, tt := range tests {
  131. result, _ := f.exec(fctx, tt.args)
  132. if !reflect.DeepEqual(result, tt.result) {
  133. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  134. }
  135. }
  136. }
  137. func TestChangedColPartition(t *testing.T) {
  138. f, ok := builtins["changed_col"]
  139. if !ok {
  140. t.Fatal("builtin not found")
  141. }
  142. contextLogger := conf.Log.WithField("rule", "testExec")
  143. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  144. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  145. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  146. var tests = []struct {
  147. args []interface{}
  148. result interface{}
  149. }{
  150. { // 0
  151. args: []interface{}{
  152. "foo",
  153. "bar",
  154. "1",
  155. },
  156. result: fmt.Errorf("first arg is not a bool but got foo"),
  157. }, { // 1
  158. args: []interface{}{
  159. true,
  160. "bar",
  161. "2",
  162. },
  163. result: "bar",
  164. }, { // 2
  165. args: []interface{}{
  166. true,
  167. "bar",
  168. "1",
  169. },
  170. result: "bar",
  171. }, { // 3
  172. args: []interface{}{
  173. true,
  174. "baz",
  175. "2",
  176. },
  177. result: "baz",
  178. }, { // 4
  179. args: []interface{}{
  180. false,
  181. nil,
  182. "1",
  183. },
  184. result: nil,
  185. }, { // 5
  186. args: []interface{}{
  187. false,
  188. "baz",
  189. "2",
  190. },
  191. result: nil,
  192. }, { // 6
  193. args: []interface{}{
  194. true,
  195. "foo",
  196. "1",
  197. },
  198. result: "foo",
  199. },
  200. }
  201. for i, tt := range tests {
  202. result, _ := f.exec(fctx, tt.args)
  203. if !reflect.DeepEqual(result, tt.result) {
  204. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  205. }
  206. }
  207. }
  208. func TestHadChangedValidation(t *testing.T) {
  209. f, ok := builtins["had_changed"]
  210. if !ok {
  211. t.Fatal("builtin not found")
  212. }
  213. var tests = []struct {
  214. args []ast.Expr
  215. err error
  216. }{
  217. {
  218. args: []ast.Expr{
  219. &ast.StringLiteral{Val: "foo"},
  220. },
  221. err: fmt.Errorf("expect more than one arg but got 1"),
  222. }, {
  223. args: []ast.Expr{
  224. &ast.StringLiteral{Val: "foo"},
  225. &ast.StringLiteral{Val: "bar"},
  226. &ast.StringLiteral{Val: "baz"},
  227. },
  228. err: fmt.Errorf("Expect bool type for parameter 1"),
  229. }, {
  230. args: []ast.Expr{
  231. &ast.IntegerLiteral{Val: 20},
  232. &ast.BooleanLiteral{Val: true},
  233. &ast.StringLiteral{Val: "baz"},
  234. },
  235. err: fmt.Errorf("Expect bool type for parameter 1"),
  236. }, {
  237. args: []ast.Expr{
  238. &ast.FieldRef{
  239. StreamName: "demo",
  240. Name: "a",
  241. AliasRef: nil,
  242. },
  243. &ast.BooleanLiteral{Val: true},
  244. &ast.StringLiteral{Val: "baz"},
  245. },
  246. err: nil,
  247. },
  248. }
  249. for i, tt := range tests {
  250. err := f.val(nil, tt.args)
  251. if !reflect.DeepEqual(err, tt.err) {
  252. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, err, tt.err)
  253. }
  254. }
  255. }
  256. func TestHadChangedExec(t *testing.T) {
  257. f, ok := builtins["had_changed"]
  258. if !ok {
  259. t.Fatal("builtin not found")
  260. }
  261. contextLogger := conf.Log.WithField("rule", "testExec")
  262. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  263. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  264. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 1)
  265. var tests = []struct {
  266. args []interface{}
  267. result interface{}
  268. }{
  269. { // 0
  270. args: []interface{}{
  271. "foo",
  272. "bar",
  273. "baz",
  274. "self",
  275. },
  276. result: fmt.Errorf("first arg is not a bool but got foo"),
  277. }, { // 1
  278. args: []interface{}{
  279. "foo",
  280. "bar",
  281. "self",
  282. },
  283. result: fmt.Errorf("first arg is not a bool but got foo"),
  284. }, { // 2
  285. args: []interface{}{
  286. true,
  287. "bar",
  288. 20,
  289. "self",
  290. },
  291. result: true,
  292. }, { // 3
  293. args: []interface{}{
  294. true,
  295. "baz",
  296. 44,
  297. "self",
  298. },
  299. result: true,
  300. }, { // 4
  301. args: []interface{}{
  302. true,
  303. "baz",
  304. 44,
  305. "self",
  306. },
  307. result: false,
  308. }, { // 5
  309. args: []interface{}{
  310. true,
  311. "foo",
  312. 44,
  313. "self",
  314. },
  315. result: true,
  316. }, { // 6
  317. args: []interface{}{
  318. true,
  319. "foo",
  320. nil,
  321. "self",
  322. },
  323. result: false,
  324. }, { // 7
  325. args: []interface{}{
  326. true,
  327. "foo",
  328. 44,
  329. "self",
  330. },
  331. result: false,
  332. }, { // 8
  333. args: []interface{}{
  334. true,
  335. "baz",
  336. 44,
  337. "self",
  338. },
  339. result: true,
  340. },
  341. }
  342. for i, tt := range tests {
  343. result, _ := f.exec(fctx, tt.args)
  344. if !reflect.DeepEqual(result, tt.result) {
  345. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  346. }
  347. }
  348. }
  349. func TestHadChangedExecAllowNull(t *testing.T) {
  350. f, ok := builtins["had_changed"]
  351. if !ok {
  352. t.Fatal("builtin not found")
  353. }
  354. contextLogger := conf.Log.WithField("rule", "testExec")
  355. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  356. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  357. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 1)
  358. var tests = []struct {
  359. args []interface{}
  360. result interface{}
  361. }{
  362. { // 0
  363. args: []interface{}{
  364. "foo",
  365. "bar",
  366. "baz",
  367. "self",
  368. },
  369. result: fmt.Errorf("first arg is not a bool but got foo"),
  370. }, { // 1
  371. args: []interface{}{
  372. "foo",
  373. "bar",
  374. "self",
  375. },
  376. result: fmt.Errorf("first arg is not a bool but got foo"),
  377. }, { // 2
  378. args: []interface{}{
  379. false,
  380. "bar",
  381. 20,
  382. "self",
  383. },
  384. result: true,
  385. }, { // 3
  386. args: []interface{}{
  387. false,
  388. "baz",
  389. nil,
  390. "self",
  391. },
  392. result: true,
  393. }, { // 4
  394. args: []interface{}{
  395. false,
  396. "baz",
  397. 44,
  398. "self",
  399. },
  400. result: true,
  401. }, { // 5
  402. args: []interface{}{
  403. false,
  404. nil,
  405. 44,
  406. "self",
  407. },
  408. result: true,
  409. }, { // 6
  410. args: []interface{}{
  411. false,
  412. "baz",
  413. 44,
  414. "self",
  415. },
  416. result: true,
  417. }, { // 7
  418. args: []interface{}{
  419. false,
  420. "baz",
  421. 44,
  422. "self",
  423. },
  424. result: false,
  425. }, { // 8
  426. args: []interface{}{
  427. false,
  428. nil,
  429. nil,
  430. "self",
  431. },
  432. result: true,
  433. }, { // 9
  434. args: []interface{}{
  435. false,
  436. "baz",
  437. 44,
  438. "self",
  439. },
  440. result: true,
  441. },
  442. }
  443. for i, tt := range tests {
  444. result, _ := f.exec(fctx, tt.args)
  445. if !reflect.DeepEqual(result, tt.result) {
  446. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  447. }
  448. }
  449. }
  450. func TestHadChangedPartition(t *testing.T) {
  451. f, ok := builtins["had_changed"]
  452. if !ok {
  453. t.Fatal("builtin not found")
  454. }
  455. contextLogger := conf.Log.WithField("rule", "testExec")
  456. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  457. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  458. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 1)
  459. var tests = []struct {
  460. args []interface{}
  461. result interface{}
  462. }{
  463. { // 0
  464. args: []interface{}{
  465. "foo",
  466. "bar",
  467. "baz",
  468. "1",
  469. },
  470. result: fmt.Errorf("first arg is not a bool but got foo"),
  471. }, { // 1
  472. args: []interface{}{
  473. "foo",
  474. "bar",
  475. "1",
  476. },
  477. result: fmt.Errorf("first arg is not a bool but got foo"),
  478. }, { // 2
  479. args: []interface{}{
  480. true,
  481. "bar",
  482. 20,
  483. "3",
  484. },
  485. result: true,
  486. }, { // 3
  487. args: []interface{}{
  488. true,
  489. "baz",
  490. 44,
  491. "2",
  492. },
  493. result: true,
  494. }, { // 4
  495. args: []interface{}{
  496. true,
  497. "baz",
  498. 44,
  499. "2",
  500. },
  501. result: false,
  502. }, { // 5
  503. args: []interface{}{
  504. true,
  505. "foo",
  506. 44,
  507. "3",
  508. },
  509. result: true,
  510. }, { // 6
  511. args: []interface{}{
  512. true,
  513. "foo",
  514. nil,
  515. "1",
  516. },
  517. result: true,
  518. }, { // 7
  519. args: []interface{}{
  520. true,
  521. "foo",
  522. 44,
  523. "2",
  524. },
  525. result: true,
  526. }, { // 8
  527. args: []interface{}{
  528. true,
  529. "baz",
  530. 44,
  531. "3",
  532. },
  533. result: true,
  534. },
  535. }
  536. for i, tt := range tests {
  537. result, _ := f.exec(fctx, tt.args)
  538. if !reflect.DeepEqual(result, tt.result) {
  539. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  540. }
  541. }
  542. }
  543. func TestLagExec(t *testing.T) {
  544. f, ok := builtins["lag"]
  545. if !ok {
  546. t.Fatal("builtin not found")
  547. }
  548. contextLogger := conf.Log.WithField("rule", "testExec")
  549. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  550. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  551. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  552. var tests = []struct {
  553. args []interface{}
  554. result interface{}
  555. }{
  556. { // 0
  557. args: []interface{}{"self"},
  558. result: fmt.Errorf("expect one two or three args but got 0"),
  559. }, { // 1
  560. args: []interface{}{
  561. "foo",
  562. "self",
  563. },
  564. result: nil,
  565. },
  566. { // 2
  567. args: []interface{}{
  568. "bar",
  569. "self",
  570. },
  571. result: "foo",
  572. },
  573. { // 3
  574. args: []interface{}{
  575. "bar",
  576. "self",
  577. },
  578. result: "bar",
  579. },
  580. { // 4
  581. args: []interface{}{
  582. "foo",
  583. "self",
  584. },
  585. result: "bar",
  586. },
  587. { // 4
  588. args: []interface{}{
  589. "foo",
  590. "self",
  591. },
  592. result: "foo",
  593. },
  594. }
  595. for i, tt := range tests {
  596. result, _ := f.exec(fctx, tt.args)
  597. if !reflect.DeepEqual(result, tt.result) {
  598. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  599. }
  600. }
  601. }
  602. func TestLagPartition(t *testing.T) {
  603. f, ok := builtins["lag"]
  604. if !ok {
  605. t.Fatal("builtin not found")
  606. }
  607. contextLogger := conf.Log.WithField("rule", "testExec")
  608. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  609. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  610. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  611. var tests = []struct {
  612. args []interface{}
  613. result interface{}
  614. }{
  615. { // 0
  616. args: []interface{}{"self"},
  617. result: fmt.Errorf("expect one two or three args but got 0"),
  618. }, { // 1
  619. args: []interface{}{
  620. "foo",
  621. "1",
  622. },
  623. result: nil,
  624. },
  625. { // 2
  626. args: []interface{}{
  627. "bar",
  628. "1",
  629. },
  630. result: "foo",
  631. },
  632. { // 3
  633. args: []interface{}{
  634. "bar",
  635. "2",
  636. },
  637. result: nil,
  638. },
  639. { // 4
  640. args: []interface{}{
  641. "foo",
  642. "1",
  643. },
  644. result: "bar",
  645. },
  646. { // 4
  647. args: []interface{}{
  648. "foo",
  649. "2",
  650. },
  651. result: "bar",
  652. },
  653. }
  654. for i, tt := range tests {
  655. result, _ := f.exec(fctx, tt.args)
  656. if !reflect.DeepEqual(result, tt.result) {
  657. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  658. }
  659. }
  660. }
  661. func TestLagExecIndexWithDefaultValue(t *testing.T) {
  662. f, ok := builtins["lag"]
  663. if !ok {
  664. t.Fatal("builtin not found")
  665. }
  666. contextLogger := conf.Log.WithField("rule", "testExec")
  667. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  668. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  669. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  670. var tests = []struct {
  671. args []interface{}
  672. result interface{}
  673. }{
  674. { // 0
  675. args: []interface{}{
  676. "foo",
  677. "bar",
  678. "baz",
  679. "baw",
  680. "self",
  681. },
  682. result: fmt.Errorf("expect one two or three args but got 4"),
  683. }, { // 1
  684. args: []interface{}{
  685. "bar",
  686. 2,
  687. "no result",
  688. "self",
  689. },
  690. result: "no result",
  691. },
  692. { // 2
  693. args: []interface{}{
  694. "bar",
  695. 2,
  696. "no result",
  697. "self",
  698. },
  699. result: "no result",
  700. },
  701. { // 3
  702. args: []interface{}{
  703. "foo",
  704. 2,
  705. "no result",
  706. "self",
  707. },
  708. result: "bar",
  709. },
  710. { // 4
  711. args: []interface{}{
  712. "foo",
  713. 2,
  714. "no result",
  715. "self",
  716. },
  717. result: "bar",
  718. },
  719. { // 4
  720. args: []interface{}{
  721. "foo",
  722. 2,
  723. "no result",
  724. "self",
  725. },
  726. result: "foo",
  727. },
  728. }
  729. for i, tt := range tests {
  730. result, _ := f.exec(fctx, tt.args)
  731. if !reflect.DeepEqual(result, tt.result) {
  732. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  733. }
  734. }
  735. }
  736. func TestLagExecIndex(t *testing.T) {
  737. f, ok := builtins["lag"]
  738. if !ok {
  739. t.Fatal("builtin not found")
  740. }
  741. contextLogger := conf.Log.WithField("rule", "testExec")
  742. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  743. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  744. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  745. var tests = []struct {
  746. args []interface{}
  747. result interface{}
  748. }{
  749. { // 0
  750. args: []interface{}{
  751. "foo",
  752. "bar",
  753. "baz",
  754. "baw",
  755. "self",
  756. },
  757. result: fmt.Errorf("expect one two or three args but got 4"),
  758. }, { // 1
  759. args: []interface{}{
  760. "bar",
  761. 2,
  762. "self",
  763. },
  764. result: nil,
  765. },
  766. { // 2
  767. args: []interface{}{
  768. "bar",
  769. 2,
  770. "self",
  771. },
  772. result: nil,
  773. },
  774. { // 3
  775. args: []interface{}{
  776. "foo",
  777. 2,
  778. "self",
  779. },
  780. result: "bar",
  781. },
  782. { // 4
  783. args: []interface{}{
  784. "foo",
  785. 2,
  786. "self",
  787. },
  788. result: "bar",
  789. },
  790. { // 4
  791. args: []interface{}{
  792. "foo",
  793. 2,
  794. "self",
  795. },
  796. result: "foo",
  797. },
  798. }
  799. for i, tt := range tests {
  800. result, _ := f.exec(fctx, tt.args)
  801. if !reflect.DeepEqual(result, tt.result) {
  802. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  803. }
  804. }
  805. }
  806. func TestLatestExec(t *testing.T) {
  807. f, ok := builtins["latest"]
  808. if !ok {
  809. t.Fatal("builtin not found")
  810. }
  811. contextLogger := conf.Log.WithField("rule", "testExec")
  812. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  813. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  814. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  815. var tests = []struct {
  816. args []interface{}
  817. result interface{}
  818. }{
  819. { // 0
  820. args: []interface{}{"self"},
  821. result: fmt.Errorf("expect one or two args but got 0"),
  822. }, { // 1
  823. args: []interface{}{
  824. "foo",
  825. "self",
  826. },
  827. result: "foo",
  828. },
  829. { // 2
  830. args: []interface{}{
  831. nil,
  832. "self",
  833. },
  834. result: "foo",
  835. },
  836. { // 3
  837. args: []interface{}{
  838. "bar",
  839. "self",
  840. },
  841. result: "bar",
  842. },
  843. { // 4
  844. args: []interface{}{
  845. nil,
  846. "self",
  847. },
  848. result: "bar",
  849. },
  850. { // 4
  851. args: []interface{}{
  852. "foo",
  853. "self",
  854. },
  855. result: "foo",
  856. },
  857. }
  858. for i, tt := range tests {
  859. result, _ := f.exec(fctx, tt.args)
  860. if !reflect.DeepEqual(result, tt.result) {
  861. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  862. }
  863. }
  864. }
  865. func TestLatestPartition(t *testing.T) {
  866. f, ok := builtins["latest"]
  867. if !ok {
  868. t.Fatal("builtin not found")
  869. }
  870. contextLogger := conf.Log.WithField("rule", "testExec")
  871. ctx := kctx.WithValue(kctx.Background(), kctx.LoggerKey, contextLogger)
  872. tempStore, _ := state.CreateStore("mockRule0", api.AtMostOnce)
  873. fctx := kctx.NewDefaultFuncContext(ctx.WithMeta("mockRule0", "test", tempStore), 2)
  874. var tests = []struct {
  875. args []interface{}
  876. result interface{}
  877. }{
  878. { // 0
  879. args: []interface{}{"self"},
  880. result: fmt.Errorf("expect one or two args but got 0"),
  881. }, { // 1
  882. args: []interface{}{
  883. "foo",
  884. "2",
  885. },
  886. result: "foo",
  887. },
  888. { // 2
  889. args: []interface{}{
  890. nil,
  891. "dd",
  892. "1",
  893. },
  894. result: "dd",
  895. },
  896. { // 3
  897. args: []interface{}{
  898. "bar",
  899. "1",
  900. },
  901. result: "bar",
  902. },
  903. { // 4
  904. args: []interface{}{
  905. nil,
  906. "2",
  907. },
  908. result: "foo",
  909. },
  910. { // 4
  911. args: []interface{}{
  912. "foo",
  913. "1",
  914. },
  915. result: "foo",
  916. },
  917. }
  918. for i, tt := range tests {
  919. result, _ := f.exec(fctx, tt.args)
  920. if !reflect.DeepEqual(result, tt.result) {
  921. t.Errorf("%d result mismatch,\ngot:\t%v \nwant:\t%v", i, result, tt.result)
  922. }
  923. }
  924. }