Skip to content

Commit 5647ad0

Browse files
committed
refactor: add more tests and benchmarks
1 parent c581da7 commit 5647ad0

File tree

3 files changed

+78
-19
lines changed

3 files changed

+78
-19
lines changed

program/c/src/oracle/model/price_model.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ void heapsort(int64_t * a, uint64_t n) {
6161
*
6262
* This implementation is chosen among other implementations such as merge-sort, quick-sort, and quick-select
6363
* because it is very fast, has small number of instructions, and has a very small memory footprint by being
64-
* in-place and is non-recursive.
64+
* in-place and is non-recursive and has a nlogn worst-case time complexity.
6565
*/
6666
int64_t *
6767
price_model_core( uint64_t cnt,

program/c/src/oracle/model/test_price_model.c

+27-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,32 @@ int test_price_model() {
2525
int64_t quote [N];
2626
int64_t val [3];
2727

28+
/* Brute force validate small sizes via the 0-1 principle. */
29+
for( int cnt=0; cnt<=24; cnt++ ) {
30+
for( long mask=0L; mask<(1L<<cnt); mask++ ) {
31+
for( int i=0; i<cnt; i++ ) quote[i] = (int64_t) ((mask>>i) & 1L);
32+
33+
memcpy( quote, quote0, sizeof(int64_t)*(size_t)cnt );
34+
if( price_model_core( cnt, quote, val+0, val+1, val+2)!=quote ) { printf( "FAIL (01-compose)\n" ); return 1; }
35+
36+
/* Validate the results */
37+
38+
/* Although being sorted is not necessary it gives us more confidence about the correctness of the model */
39+
qsort( quote0, (size_t)cnt, sizeof(int64_t), qcmp );
40+
if( memcmp( quote, quote0, sizeof(int64_t)*(size_t)cnt ) ) { printf( "FAIL (01-sort)\n" ); return 1; }
41+
42+
uint64_t p25_idx = cnt>>2;
43+
uint64_t p50_idx = cnt>>1;
44+
uint64_t p75_idx = cnt - (uint64_t)1 - p25_idx;
45+
uint64_t is_even = (uint64_t)!(cnt & (uint64_t)1);
46+
47+
if( val[0]!=quote[ p25_idx ] ) { printf( "FAIL (01-p25)\n" ); return 1; }
48+
if( val[1]!=avg_2_int64( quote[ p50_idx-is_even ], quote[ p50_idx ] ) ) { printf( "FAIL (01-p50)\n" ); return 1; }
49+
if( val[2]!=quote[ p75_idx ] ) { printf( "FAIL (01-p75)\n" ); return 1; }
50+
}
51+
}
52+
53+
/* Test using randomized inputs */
2854
for( int iter=0; iter<10000000; iter++ ) {
2955

3056
/* Generate a random test */
@@ -39,9 +65,7 @@ int test_price_model() {
3965

4066
/* Validate the results */
4167

42-
/*
43-
* Although being sorted is not necessary it gives us more confidence about the correctness of the model.
44-
*/
68+
/* Although being sorted is not necessary it gives us more confidence about the correctness of the model */
4569
qsort( quote0, (size_t)cnt, sizeof(int64_t), qcmp );
4670
if( memcmp( quote, quote0, sizeof(int64_t)*(size_t)cnt ) ) { printf( "FAIL (sort)\n" ); return 1; }
4771

program/rust/src/tests/test_benchmark.rs

+50-15
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,17 @@ use {
1717
},
1818
};
1919

20+
#[derive(Clone, Copy, Debug)]
21+
enum TestingStrategy {
22+
Random,
23+
SimilarPrices,
24+
}
25+
2026
/// Benchmark the execution of the oracle program
21-
async fn run_benchmark(num_publishers: usize) -> Result<(), Box<dyn std::error::Error>> {
27+
async fn run_benchmark(
28+
num_publishers: usize,
29+
strategy: TestingStrategy,
30+
) -> Result<(), Box<dyn std::error::Error>> {
2231
let mut sim = PythSimulator::new().await;
2332

2433
let mapping_keypair = sim.init_mapping().await?;
@@ -40,14 +49,20 @@ async fn run_benchmark(num_publishers: usize) -> Result<(), Box<dyn std::error::
4049
let mut rnd = rand::rngs::SmallRng::seed_from_u64(14);
4150

4251
for kp in publishers_keypairs.iter() {
43-
// The ranges are chosen to create overlap between
44-
// publishers price set (price-conf, price, price + conf)
45-
let quote = Quote {
46-
price: rnd.gen_range(10000..11000),
47-
confidence: rnd.gen_range(1..1000),
48-
status: PC_STATUS_TRADING,
52+
let quote = match strategy {
53+
TestingStrategy::Random => Quote {
54+
price: rnd.gen_range(10000..11000),
55+
confidence: rnd.gen_range(1..1000),
56+
status: PC_STATUS_TRADING,
57+
},
58+
TestingStrategy::SimilarPrices => Quote {
59+
price: rnd.gen_range(10..12),
60+
confidence: rnd.gen_range(1..3),
61+
status: PC_STATUS_TRADING,
62+
},
4963
};
5064

65+
5166
sim.upd_price(kp, price_pubkey, quote).await?;
5267
}
5368

@@ -67,21 +82,41 @@ async fn run_benchmark(num_publishers: usize) -> Result<(), Box<dyn std::error::
6782
}
6883

6984
#[tokio::test]
70-
async fn test_benchmark_64_pubs() -> Result<(), Box<dyn std::error::Error>> {
71-
run_benchmark(64).await
85+
async fn test_benchmark_64_pubs_random() -> Result<(), Box<dyn std::error::Error>> {
86+
run_benchmark(64, TestingStrategy::Random).await
87+
}
88+
89+
#[tokio::test]
90+
async fn test_benchmark_64_pubs_similar_prices() -> Result<(), Box<dyn std::error::Error>> {
91+
run_benchmark(64, TestingStrategy::SimilarPrices).await
92+
}
93+
94+
#[tokio::test]
95+
async fn test_benchmark_32_pubs_random() -> Result<(), Box<dyn std::error::Error>> {
96+
run_benchmark(32, TestingStrategy::Random).await
97+
}
98+
99+
#[tokio::test]
100+
async fn test_benchmark_32_pubs_similar_prices() -> Result<(), Box<dyn std::error::Error>> {
101+
run_benchmark(32, TestingStrategy::SimilarPrices).await
102+
}
103+
104+
#[tokio::test]
105+
async fn test_benchmark_16_pubs_random() -> Result<(), Box<dyn std::error::Error>> {
106+
run_benchmark(16, TestingStrategy::Random).await
72107
}
73108

74109
#[tokio::test]
75-
async fn test_benchmark_32_pubs() -> Result<(), Box<dyn std::error::Error>> {
76-
run_benchmark(32).await
110+
async fn test_benchmark_16_pubs_similar_prices() -> Result<(), Box<dyn std::error::Error>> {
111+
run_benchmark(16, TestingStrategy::SimilarPrices).await
77112
}
78113

79114
#[tokio::test]
80-
async fn test_benchmark_16_pubs() -> Result<(), Box<dyn std::error::Error>> {
81-
run_benchmark(16).await
115+
async fn test_benchmark_8_pubs_random() -> Result<(), Box<dyn std::error::Error>> {
116+
run_benchmark(8, TestingStrategy::Random).await
82117
}
83118

84119
#[tokio::test]
85-
async fn test_benchmark_8_pubs() -> Result<(), Box<dyn std::error::Error>> {
86-
run_benchmark(8).await
120+
async fn test_benchmark_8_pubs_similar_prices() -> Result<(), Box<dyn std::error::Error>> {
121+
run_benchmark(8, TestingStrategy::SimilarPrices).await
87122
}

0 commit comments

Comments
 (0)