|
1 | 1 | #[cfg(test)] |
2 | 2 | mod tests { |
| 3 | + use std::fmt::Debug; |
| 4 | + use tokio_postgres::types::{FromSql, ToSql}; |
3 | 5 | use tokio_postgres::SimpleQueryMessage; |
4 | 6 |
|
5 | 7 | use crate::common::{clear, connect_with_tls, random_id, trace, PROXY}; |
@@ -417,164 +419,109 @@ mod tests { |
417 | 419 |
|
418 | 420 | #[tokio::test] |
419 | 421 | async fn map_ore_order_int2() { |
420 | | - trace(); |
421 | | - |
422 | | - clear().await; |
423 | | - |
424 | | - let client = connect_with_tls(PROXY).await; |
425 | | - |
426 | | - let n_one = 10i16; |
427 | | - let n_two = 20i16; |
428 | | - let n_three = 30i16; |
429 | | - |
430 | | - let sql = " |
431 | | - INSERT INTO encrypted (id, encrypted_int2) |
432 | | - VALUES ($1, $2), ($3, $4), ($5, $6) |
433 | | - "; |
434 | | - |
435 | | - client |
436 | | - .query( |
437 | | - sql, |
438 | | - &[ |
439 | | - &random_id(), |
440 | | - &n_two, |
441 | | - &random_id(), |
442 | | - &n_one, |
443 | | - &random_id(), |
444 | | - &n_three, |
445 | | - ], |
446 | | - ) |
447 | | - .await |
448 | | - .unwrap(); |
449 | | - |
450 | | - let sql = "SELECT encrypted_int2 FROM encrypted ORDER BY encrypted_int2"; |
451 | | - let rows = client.query(sql, &[]).await.unwrap(); |
452 | | - |
453 | | - let actual = rows.iter().map(|row| row.get(0)).collect::<Vec<i16>>(); |
454 | | - let expected = vec![n_one, n_two, n_three]; |
455 | | - |
456 | | - assert_eq!(actual, expected); |
| 422 | + let values: Vec<i16> = vec![-100, -10, -1, 0, 1, 5, 10, 20, 100, 200]; |
| 423 | + map_ore_order_generic("encrypted_int2", values, "ASC").await; |
457 | 424 | } |
458 | 425 |
|
459 | 426 | #[tokio::test] |
460 | 427 | async fn map_ore_order_int2_desc() { |
461 | | - trace(); |
462 | | - |
463 | | - clear().await; |
464 | | - |
465 | | - let client = connect_with_tls(PROXY).await; |
466 | | - |
467 | | - let n_one = 10i16; |
468 | | - let n_two = 20i16; |
469 | | - let n_three = 30i16; |
470 | | - |
471 | | - let sql = " |
472 | | - INSERT INTO encrypted (id, encrypted_int2) |
473 | | - VALUES ($1, $2), ($3, $4), ($5, $6) |
474 | | - "; |
475 | | - |
476 | | - client |
477 | | - .query( |
478 | | - sql, |
479 | | - &[ |
480 | | - &random_id(), |
481 | | - &n_two, |
482 | | - &random_id(), |
483 | | - &n_one, |
484 | | - &random_id(), |
485 | | - &n_three, |
486 | | - ], |
487 | | - ) |
488 | | - .await |
489 | | - .unwrap(); |
490 | | - |
491 | | - let sql = "SELECT encrypted_int2 FROM encrypted ORDER BY encrypted_int2 DESC"; |
492 | | - let rows = client.query(sql, &[]).await.unwrap(); |
493 | | - |
494 | | - let actual = rows.iter().map(|row| row.get(0)).collect::<Vec<i16>>(); |
495 | | - let expected = vec![n_three, n_two, n_one]; |
496 | | - |
497 | | - assert_eq!(actual, expected); |
| 428 | + let values: Vec<i16> = vec![-100, -10, -1, 0, 1, 5, 10, 20, 100, 200]; |
| 429 | + map_ore_order_generic("encrypted_int2", values, "DESC").await; |
498 | 430 | } |
499 | 431 |
|
500 | 432 | #[tokio::test] |
501 | 433 | async fn map_ore_order_int4() { |
502 | | - trace(); |
503 | | - |
504 | | - clear().await; |
505 | | - |
506 | | - let client = connect_with_tls(PROXY).await; |
| 434 | + let values: Vec<i32> = vec![-50_000, -1_000, -1, 0, 1, 42, 1_000, 10_000, 50_000, 100_000]; |
| 435 | + map_ore_order_generic("encrypted_int4", values, "ASC").await; |
| 436 | + } |
507 | 437 |
|
508 | | - let n_one = 10i32; |
509 | | - let n_two = 20i32; |
510 | | - let n_three = 30i32; |
| 438 | + #[tokio::test] |
| 439 | + async fn map_ore_order_int4_desc() { |
| 440 | + let values: Vec<i32> = vec![-50_000, -1_000, -1, 0, 1, 42, 1_000, 10_000, 50_000, 100_000]; |
| 441 | + map_ore_order_generic("encrypted_int4", values, "DESC").await; |
| 442 | + } |
511 | 443 |
|
512 | | - let sql = " |
513 | | - INSERT INTO encrypted (id, encrypted_int4) |
514 | | - VALUES ($1, $2), ($3, $4), ($5, $6) |
515 | | - "; |
| 444 | + #[tokio::test] |
| 445 | + async fn map_ore_order_int8() { |
| 446 | + let values: Vec<i64> = vec![-1_000_000, -10_000, -1, 0, 1, 42, 10_000, 100_000, 1_000_000, 9_999_999]; |
| 447 | + map_ore_order_generic("encrypted_int8", values, "ASC").await; |
| 448 | + } |
516 | 449 |
|
517 | | - client |
518 | | - .query( |
519 | | - sql, |
520 | | - &[ |
521 | | - &random_id(), |
522 | | - &n_two, |
523 | | - &random_id(), |
524 | | - &n_one, |
525 | | - &random_id(), |
526 | | - &n_three, |
527 | | - ], |
528 | | - ) |
529 | | - .await |
530 | | - .unwrap(); |
| 450 | + #[tokio::test] |
| 451 | + async fn map_ore_order_int8_desc() { |
| 452 | + let values: Vec<i64> = vec![-1_000_000, -10_000, -1, 0, 1, 42, 10_000, 100_000, 1_000_000, 9_999_999]; |
| 453 | + map_ore_order_generic("encrypted_int8", values, "DESC").await; |
| 454 | + } |
531 | 455 |
|
532 | | - let sql = "SELECT encrypted_int4 FROM encrypted ORDER BY encrypted_int4"; |
533 | | - let rows = client.query(sql, &[]).await.unwrap(); |
| 456 | + #[tokio::test] |
| 457 | + async fn map_ore_order_float8() { |
| 458 | + let values: Vec<f64> = vec![-99.9, -1.5, -0.001, 0.0, 0.001, 1.5, 3.14, 42.0, 99.9, 1000.5]; |
| 459 | + map_ore_order_generic("encrypted_float8", values, "ASC").await; |
| 460 | + } |
534 | 461 |
|
535 | | - let actual = rows.iter().map(|row| row.get(0)).collect::<Vec<i32>>(); |
536 | | - let expected = vec![n_one, n_two, n_three]; |
| 462 | + #[tokio::test] |
| 463 | + async fn map_ore_order_float8_desc() { |
| 464 | + let values: Vec<f64> = vec![-99.9, -1.5, -0.001, 0.0, 0.001, 1.5, 3.14, 42.0, 99.9, 1000.5]; |
| 465 | + map_ore_order_generic("encrypted_float8", values, "DESC").await; |
| 466 | + } |
537 | 467 |
|
538 | | - assert_eq!(actual, expected); |
| 468 | + /// Returns indices in zigzag order so insertion is never accidentally sorted. |
| 469 | + /// For len=5: [4, 0, 3, 1, 2] |
| 470 | + fn interleaved_indices(len: usize) -> Vec<usize> { |
| 471 | + let mut indices = Vec::with_capacity(len); |
| 472 | + let mut lo = 0; |
| 473 | + let mut hi = len; |
| 474 | + let mut take_hi = true; |
| 475 | + while lo < hi { |
| 476 | + if take_hi { |
| 477 | + hi -= 1; |
| 478 | + indices.push(hi); |
| 479 | + } else { |
| 480 | + indices.push(lo); |
| 481 | + lo += 1; |
| 482 | + } |
| 483 | + take_hi = !take_hi; |
| 484 | + } |
| 485 | + indices |
539 | 486 | } |
540 | 487 |
|
541 | | - #[tokio::test] |
542 | | - async fn map_ore_order_int8() { |
| 488 | + /// Generic ORE ordering test. |
| 489 | + /// |
| 490 | + /// `values` must be provided in ascending sorted order. |
| 491 | + /// Values are inserted in interleaved (non-sorted) order, then verified |
| 492 | + /// via ORDER BY in the given direction. |
| 493 | + async fn map_ore_order_generic<T>(col_name: &str, values: Vec<T>, direction: &str) |
| 494 | + where |
| 495 | + for<'a> T: Clone + PartialEq + ToSql + Sync + FromSql<'a> + PartialOrd + Debug, |
| 496 | + { |
543 | 497 | trace(); |
544 | 498 |
|
545 | 499 | clear().await; |
546 | 500 |
|
547 | 501 | let client = connect_with_tls(PROXY).await; |
548 | 502 |
|
549 | | - let n_one = 10i64; |
550 | | - let n_two = 20i64; |
551 | | - let n_three = 30i64; |
| 503 | + let insert_sql = format!("INSERT INTO encrypted (id, {col_name}) VALUES ($1, $2)"); |
552 | 504 |
|
553 | | - let sql = " |
554 | | - INSERT INTO encrypted (id, encrypted_int8) |
555 | | - VALUES ($1, $2), ($3, $4), ($5, $6) |
556 | | - "; |
| 505 | + // Insert in interleaved order to avoid accidentally-sorted insertion |
| 506 | + for idx in interleaved_indices(values.len()) { |
| 507 | + client |
| 508 | + .query(&insert_sql, &[&random_id(), &values[idx]]) |
| 509 | + .await |
| 510 | + .unwrap(); |
| 511 | + } |
557 | 512 |
|
558 | | - client |
559 | | - .query( |
560 | | - sql, |
561 | | - &[ |
562 | | - &random_id(), |
563 | | - &n_two, |
564 | | - &random_id(), |
565 | | - &n_one, |
566 | | - &random_id(), |
567 | | - &n_three, |
568 | | - ], |
569 | | - ) |
570 | | - .await |
571 | | - .unwrap(); |
| 513 | + let select_sql = format!( |
| 514 | + "SELECT {col_name} FROM encrypted ORDER BY {col_name} {direction}" |
| 515 | + ); |
| 516 | + let rows = client.query(&select_sql, &[]).await.unwrap(); |
572 | 517 |
|
573 | | - let sql = "SELECT encrypted_int8 FROM encrypted ORDER BY encrypted_int8"; |
574 | | - let rows = client.query(sql, &[]).await.unwrap(); |
| 518 | + let actual: Vec<T> = rows.iter().map(|row| row.get(0)).collect(); |
575 | 519 |
|
576 | | - let actual = rows.iter().map(|row| row.get(0)).collect::<Vec<i64>>(); |
577 | | - let expected = vec![n_one, n_two, n_three]; |
| 520 | + let expected: Vec<T> = if direction == "DESC" { |
| 521 | + values.into_iter().rev().collect() |
| 522 | + } else { |
| 523 | + values |
| 524 | + }; |
578 | 525 |
|
579 | 526 | assert_eq!(actual, expected); |
580 | 527 | } |
|
0 commit comments