@@ -9,21 +9,33 @@ use super::{TestAnalytics, TestAnalyticsWriter};
99
1010#[ pyclass]
1111pub struct BinaryFormatWriter {
12- writer : TestAnalyticsWriter ,
12+ writer : Option < TestAnalyticsWriter > ,
1313}
1414
15+ #[ pymethods]
1516impl BinaryFormatWriter {
17+ #[ new]
1618 pub fn new ( ) -> Self {
1719 Self {
18- writer : TestAnalyticsWriter :: new ( 60 ) ,
20+ writer : Some ( TestAnalyticsWriter :: new ( 60 ) ) ,
1921 }
2022 }
23+
24+ #[ staticmethod]
25+ pub fn open ( buffer : & [ u8 ] ) -> anyhow:: Result < Self > {
26+ let format = TestAnalytics :: parse ( buffer, 0 ) ?;
27+ let writer = TestAnalyticsWriter :: from_existing_format ( & format) ?;
28+ Ok ( Self {
29+ writer : Some ( writer) ,
30+ } )
31+ }
32+
2133 pub fn add_testruns (
2234 & mut self ,
2335 timestamp : u32 ,
2436 commit_hash : & str ,
25- flags : & [ & str ] ,
26- testruns : & [ Testrun ] ,
37+ flags : Vec < String > ,
38+ testruns : Vec < Testrun > ,
2739 ) -> anyhow:: Result < ( ) > {
2840 let commit_hash_base16 = if commit_hash. len ( ) > 40 {
2941 commit_hash
@@ -35,29 +47,61 @@ impl BinaryFormatWriter {
3547 let mut commit_hash = super :: CommitHash :: default ( ) ;
3648 base16ct:: mixed:: decode ( commit_hash_base16, & mut commit_hash. 0 ) ?;
3749
38- let mut session = self . writer . start_session ( timestamp, commit_hash, flags) ;
50+ let writer = self
51+ . writer
52+ . as_mut ( )
53+ . context ( "writer was already serialized" ) ?;
54+
55+ let flags: Vec < _ > = flags. iter ( ) . map ( |s| s. as_str ( ) ) . collect ( ) ;
56+ let mut session = writer. start_session ( timestamp, commit_hash, & flags) ;
3957 for test in testruns {
40- session. insert ( test) ;
58+ session. insert ( & test) ;
4159 }
4260 Ok ( ( ) )
4361 }
4462
45- pub fn serialize ( self ) -> anyhow:: Result < Vec < u8 > > {
63+ pub fn serialize ( & mut self ) -> anyhow:: Result < Vec < u8 > > {
64+ let writer = self
65+ . writer
66+ . take ( )
67+ . context ( "writer was already serialized" ) ?;
4668 let mut buffer = vec ! [ ] ;
47- self . writer . serialize ( & mut buffer) ?;
69+ writer. serialize ( & mut buffer) ?;
4870 Ok ( buffer)
4971 }
5072}
5173
5274#[ pyclass]
5375pub struct AggregationReader {
54- buffer : Vec < u8 > ,
76+ _buffer : Vec < u8 > ,
5577 format : TestAnalytics < ' static > ,
5678}
5779
58- #[ pyclass]
80+ #[ pyclass( get_all ) ]
5981pub struct TestAggregate {
60- // TODO
82+ pub name : String ,
83+ // TODO:
84+ pub test_id : String ,
85+
86+ pub testsuite : Option < String > ,
87+ pub flags : Vec < String > ,
88+
89+ pub failure_rate : f32 ,
90+ pub flake_rate : f32 ,
91+
92+ // TODO:
93+ pub updated_at : u32 ,
94+ pub avg_duration : f64 ,
95+
96+ pub total_fail_count : u32 ,
97+ pub total_flaky_fail_count : u32 ,
98+ pub total_pass_count : u32 ,
99+ pub total_skip_count : u32 ,
100+
101+ pub commits_where_fail : usize ,
102+
103+ // TODO:
104+ pub last_duration : f32 ,
61105}
62106
63107#[ pymethods]
@@ -69,16 +113,48 @@ impl AggregationReader {
69113 // which we do not mutate, and which outlives the parsed format.
70114 let format = unsafe { transmute ( format) } ;
71115
72- Ok ( Self { buffer, format } )
116+ Ok ( Self {
117+ _buffer : buffer,
118+ format,
119+ } )
73120 }
74121
75- #[ pyo3( signature = ( interval_start, interval_end, flag =None ) ) ]
122+ #[ pyo3( signature = ( interval_start, interval_end, flags =None ) ) ]
76123 pub fn get_test_aggregates (
77124 & self ,
78125 interval_start : usize ,
79126 interval_end : usize ,
80- flag : Option < & str > ,
81- ) -> Vec < TestAggregate > {
82- vec ! [ ]
127+ flags : Option < Vec < String > > ,
128+ ) -> anyhow:: Result < Vec < TestAggregate > > {
129+ let flags: Option < Vec < _ > > = flags
130+ . as_ref ( )
131+ . map ( |flags| flags. iter ( ) . map ( |flag| flag. as_str ( ) ) . collect ( ) ) ;
132+ let desired_range = interval_start..interval_end;
133+
134+ let tests = self . format . tests ( desired_range, flags. as_deref ( ) ) ?;
135+ let mut collected_tests = vec ! [ ] ;
136+
137+ for test in tests {
138+ let test = test?;
139+
140+ collected_tests. push ( TestAggregate {
141+ name : test. name ( ) ?. into ( ) ,
142+ test_id : "TODO" . into ( ) ,
143+ testsuite : Some ( test. testsuite ( ) ?. into ( ) ) ,
144+ flags : test. flags ( ) ?. into_iter ( ) . map ( |s| s. into ( ) ) . collect ( ) ,
145+ failure_rate : test. aggregates ( ) . failure_rate ,
146+ flake_rate : test. aggregates ( ) . flake_rate ,
147+ updated_at : 0 , // TODO
148+ avg_duration : test. aggregates ( ) . avg_duration ,
149+ total_fail_count : test. aggregates ( ) . total_fail_count ,
150+ total_flaky_fail_count : test. aggregates ( ) . total_flaky_fail_count ,
151+ total_pass_count : test. aggregates ( ) . total_pass_count ,
152+ total_skip_count : test. aggregates ( ) . total_skip_count ,
153+ commits_where_fail : test. aggregates ( ) . failing_commits ,
154+ last_duration : 0. , // TODO
155+ } ) ;
156+ }
157+
158+ Ok ( collected_tests)
83159 }
84160}
0 commit comments