@@ -274,7 +274,7 @@ mod test {
274274 test_versions ! { produce_agg_job_req_skip_hpke_decrypt_err }
275275
276276 fn produce_agg_job_req_skip_time_too_stale ( version : DapVersion ) {
277- let t = AggregationJobTest :: new ( TEST_VDAF , HpkeKemId :: X25519HkdfSha256 , version) ;
277+ let mut t = AggregationJobTest :: new ( TEST_VDAF , HpkeKemId :: X25519HkdfSha256 , version) ;
278278 let reports = vec ! [ t
279279 . task_config
280280 . vdaf
@@ -287,6 +287,7 @@ mod test {
287287 )
288288 . unwrap( ) ] ;
289289
290+ t. task_config . not_before = t. valid_report_time_range ( ) . start - 2 ;
290291 let ( agg_job_state, _agg_job_init_req) =
291292 t. produce_agg_job_req ( & DapAggregationParam :: Empty , reports) ;
292293 assert_eq ! ( agg_job_state. report_count( ) , 0 ) ;
@@ -298,6 +299,30 @@ mod test {
298299
299300 test_versions ! { produce_agg_job_req_skip_time_too_stale }
300301
302+ fn produce_agg_job_req_skip_time_before_not_before ( version : DapVersion ) {
303+ let t = AggregationJobTest :: new ( TEST_VDAF , HpkeKemId :: X25519HkdfSha256 , version) ;
304+ let reports = vec ! [ t
305+ . task_config
306+ . vdaf
307+ . produce_report(
308+ & t. client_hpke_config_list,
309+ t. task_config. not_before - 1 ,
310+ & t. task_id,
311+ DapMeasurement :: U32Vec ( vec![ 1 ; 10 ] ) ,
312+ t. task_config. version,
313+ )
314+ . unwrap( ) ] ;
315+ let ( agg_job_state, _agg_job_init_req) =
316+ t. produce_agg_job_req ( & DapAggregationParam :: Empty , reports) ;
317+ assert_eq ! ( agg_job_state. report_count( ) , 0 ) ;
318+
319+ assert_metrics_include ! ( t. leader_registry, {
320+ r#"report_counter{env="test_leader",host="leader.com",status="rejected_task_not_started"}"# : 1 ,
321+ } ) ;
322+ }
323+
324+ test_versions ! { produce_agg_job_req_skip_time_before_not_before}
325+
301326 fn produce_agg_job_req_skip_time_too_early ( version : DapVersion ) {
302327 let t = AggregationJobTest :: new ( TEST_VDAF , HpkeKemId :: X25519HkdfSha256 , version) ;
303328 let reports = vec ! [ t
@@ -403,6 +428,7 @@ mod test {
403428 // Temporarily overwrite the valid report time range so that the Leader accepts the
404429 // out-of-range report and produces the request.
405430 let tmp = t. valid_report_range . clone ( ) ;
431+ t. task_config . not_before = t. valid_report_time_range ( ) . start - 2 ;
406432 t. valid_report_range = 0 ..u64:: MAX ;
407433 let ( _, agg_job_init_req) =
408434 t. produce_agg_job_req ( & DapAggregationParam :: Empty , reports. clone ( ) ) ;
@@ -420,6 +446,40 @@ mod test {
420446
421447 test_versions ! { handle_agg_job_req_skip_time_too_stale }
422448
449+ fn handle_agg_job_req_skip_time_before_not_before ( version : DapVersion ) {
450+ let mut t = AggregationJobTest :: new ( TEST_VDAF , HpkeKemId :: X25519HkdfSha256 , version) ;
451+ let reports = vec ! [ t
452+ . task_config
453+ . vdaf
454+ . produce_report(
455+ & t. client_hpke_config_list,
456+ t. task_config. not_before - 1 ,
457+ & t. task_id,
458+ DapMeasurement :: U32Vec ( vec![ 1 ; 10 ] ) ,
459+ t. task_config. version,
460+ )
461+ . unwrap( ) ] ;
462+
463+ let agg_job_init_req = {
464+ // Temporarily overwrite the task_config not_before time so that the Leader accepts the
465+ // out-of-range report and produces the request.
466+ t. task_config . not_before -= 2 ;
467+ let ( _, agg_job_init_req) =
468+ t. produce_agg_job_req ( & DapAggregationParam :: Empty , reports. clone ( ) ) ;
469+ t. task_config . not_before += 2 ;
470+ agg_job_init_req
471+ } ;
472+ let ( _agg_span, agg_job_resp) = t. handle_agg_job_req ( agg_job_init_req) ;
473+
474+ assert_eq ! ( agg_job_resp. transitions. len( ) , 1 ) ;
475+ assert_matches ! (
476+ agg_job_resp. transitions[ 0 ] . var,
477+ TransitionVar :: Failed ( ReportError :: TaskNotStarted )
478+ ) ;
479+ }
480+
481+ test_versions ! { handle_agg_job_req_skip_time_before_not_before}
482+
423483 fn handle_agg_job_req_skip_time_too_early ( version : DapVersion ) {
424484 let mut t = AggregationJobTest :: new ( TEST_VDAF , HpkeKemId :: X25519HkdfSha256 , version) ;
425485 let reports = vec ! [ t
0 commit comments