funcs_datetime_test.go 26 KB

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