okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
955c14d
main
1//// Trace actual BEAM reads and decodes: E2E cannot observe discarded matches, 2//// sparse keyset query counts, or how many source and node rows were decoded. 3 4import albedo/daemon/conversation 5import albedo/daemon/store 6import albedo/harness/extensions/lcm/graph 7import albedo/harness/runtime 8import albedo/harness/search 9import albedo/harness/tool 10import albedo/openai_api/types 11import gleam/dynamic/decode 12import gleam/erlang/process 13import gleam/list 14import gleam/option .{ None } 15import gleeunit/should 16import sqlight 17 18pub type Counts { 19Counts ( pages : Int , decoded : Int , sources : Int , nodes : Int , kept : Int ) 20} 21 22@external ( erlang , "albedo_retrieval_test_support" , "measure" ) 23fn measure ( owner : process . Pid , run : fn () -> a) -> #( a, Counts ) 24 25@external ( erlang , "albedo_conversation" , "pack" ) 26fn pack ( input : types . Input ) -> BitArray 27 28fn fixture () -> #( runtime . Runtime , store . Store ) { 29// No extensions: this module measures store, search, graph and tool reads 30// directly, so the default install would put 43 extensions' initialisers 31// and schema migrations inside runtime.start's 10s start ack for tables 32// none of the queries touch. The two schemas the queries need are created 33// below. 34let assert Ok ( host ) = runtime . start_with_extensions ( ":memory:" , []) 35let ledger = runtime . ledger ( host ) 36let assert Ok ( _ ) = conversation . initialise ( ledger ) 37let assert Ok ( _ ) = graph . initialise ( ledger ) 38let _ = 39list . each ([ "wanted" , "other" ], fn ( session ) { 40let assert Ok ( _ ) = 41conversation . create ( 42ledger , 43conversation . Info ( 44session , 45"fixture" , 46"/tmp" , 47"fixture" , 48"fixture" , 49types . Responses , 50conversation . Idle , 51None , 52None , 53), 54) 55}) 56#( host , ledger ) 57} 58 59fn insert ( ledger : store . Store , session : String , seq : Int , text : String ) -> Nil { 60let assert Ok ( _ ) = 61store . write ( 62ledger , 63"INSERT INTO transcript(seq,session,payload,row_class) VALUES(?,?,?,'user')" , 64[ 65sqlight . int ( seq ), 66sqlight . text ( session ), 67sqlight . blob ( pack ( types . User ( text ))), 68], 69) 70Nil 71} 72 73pub fn sparse_scoped_search_advances_by_rows_not_global_sequence_gaps_test () -> Nil { 74let #( host , ledger ) = fixture () 75insert ( ledger , "other" , 1 , "needle" ) 76insert ( ledger , "wanted" , 200_000 , "needle older" ) 77insert ( ledger , "other" , 400_000 , "needle" ) 78insert ( ledger , "wanted" , 600_000 , "needle newer" ) 79let #( result , counts ) = 80measure ( store . owner ( ledger ), fn () { 81search . page ( ledger , "wanted" , "needle" , 0 , 700_000 , 0 , 20 ) 82}) 83let assert Ok ( page ) = result 84page . count |> should . equal ( 2 ) 85list . map ( page . matches , fn ( match ) { match . seq }) 86|> should . equal ([ 200_000 , 600_000 ]) 87should . be_true ( counts . pages <= 4 ) 88counts . decoded |> should . equal ( 2 ) 89let #( result , counts ) = 90measure ( store . owner ( ledger ), fn () { 91search . fold ( 92ledger , 93search . Beyond ( "other" , "/tmp" ), 94"needle" , 95[], 96fn ( _ , _ ) { True }, 97fn ( found , match ) { [ match . seq , .. found ] }, 98) 99}) 100result |> should . equal ( Ok ([ 200_000 , 600_000 ])) 101should . be_true ( counts . pages <= 4 ) 102counts . decoded |> should . equal ( 2 ) 103runtime . stop ( host ) 104} 105 106pub fn exact_search_count_keeps_only_requested_twenty_matches_test () -> Nil { 107let #( host , ledger ) = fixture () 108let _ = 109list . each ( 110list . index_map ( list . repeat ( Nil , 2200 ), fn ( _ , index ) { index + 1 }), 111fn ( seq ) { insert ( ledger , "wanted" , seq , "needle" ) }, 112) 113let #( result , counts ) = 114measure ( store . owner ( ledger ), fn () { 115search . page ( ledger , "wanted" , "needle" , 0 , 3000 , 30 , 20 ) 116}) 117let assert Ok ( page ) = result 118page . count |> should . equal ( 2200 ) 119list . length ( page . matches ) |> should . equal ( 20 ) 120counts . decoded |> should . equal ( 2200 ) 121should . be_true ( counts . pages * 20 < 2200 ) 122counts . kept |> should . equal ( 20 ) 123runtime . stop ( host ) 124} 125 126pub fn node_listing_decodes_only_page_and_source_read_stops_after_page_test () -> Nil { 127let #( host , ledger ) = fixture () 128let _ = 129list . each ( 130list . index_map ( list . repeat ( Nil , 300 ), fn ( _ , index ) { index + 1 }), 131fn ( seq ) { insert ( ledger , "wanted" , seq , "body" ) }, 132) 133let assert Ok ( _ ) = 134graph . save_leaves ( 135ledger , 136"wanted" , 137list . map ( 138list . index_map ( list . repeat ( Nil , 45 ), fn ( _ , index ) { index + 1 }), 139fn ( seq ) { graph . Leaf ( seq , seq , "summary" ) }, 140), 141) 142// Positive control: the tracer observes the old full node-read operation. 143let #( all , control ) = 144measure ( store . owner ( ledger ), fn () { 145store . query ( ledger , fn ( db ) { 146store . rows ( 147db , 148"SELECT id,depth,first_seq,last_seq,summary FROM lcm_compaction_node WHERE session=? ORDER BY id" , 149[ sqlight . text ( "wanted" )], 150decode . field ( 0 , decode . int , decode . success ), 151) 152}) 153}) 154let assert Ok ( all ) = all 155list . length ( all ) |> should . equal ( 45 ) 156control . nodes |> should . equal ( 45 ) 157let #( page , counts ) = 158measure ( store . owner ( ledger ), fn () { 159graph . list_page ( ledger , "wanted" , 7 , 5 ) 160}) 161let assert Ok ( page ) = page 162page . total |> should . equal ( 45 ) 163counts . nodes |> should . equal ( 7 ) 164let assert Ok ( snapshot ) = conversation . snapshot ( ledger , "wanted" ) 165let #( page , counts ) = 166measure ( store . owner ( ledger ), fn () { 167tool . source_page ( ledger , snapshot , 200 , 300 , "row" , 0 , 1 ) 168}) 169let assert Ok (#( "[" , 1 , True )) = page 170should . be_true ( counts . sources <= 101 ) 171let #( page , counts ) = 172measure ( store . owner ( ledger ), fn () { 173tool . source_page ( ledger , snapshot , 1 , 300 , "row" , 0 , 1 ) 174}) 175let assert Ok (#( "[" , 1 , True )) = page 176should . be_true ( counts . sources > 0 && counts . sources < 300 ) 177runtime . stop ( host ) 178} 179 180pub fn excluded_global_rows_advance_cross_session_cursor_without_decoding_test () -> Nil { 181let #( host , ledger ) = fixture () 182insert ( ledger , "wanted" , 1 , "needle" ) 183let _ = 184list . each ( 185list . index_map ( list . repeat ( Nil , 2200 ), fn ( _ , index ) { index + 2 }), 186fn ( seq ) { insert ( ledger , "other" , seq , "needle" ) }, 187) 188let #( result , counts ) = 189measure ( store . owner ( ledger ), fn () { 190search . fold ( 191ledger , 192search . Beyond ( "other" , "/tmp" ), 193"needle" , 194[], 195fn ( _ , _ ) { True }, 196fn ( found , match ) { [ match . seq , .. found ] }, 197) 198}) 199result |> should . equal ( Ok ([ 1 ])) 200should . be_true ( counts . pages * 20 < 2200 ) 201counts . decoded |> should . equal ( 1 ) 202runtime . stop ( host ) 203}