@ -4,7 +4,6 @@ import os 
			
		
	
		
			
				
					import  random  
			
		
	
		
			
				
					import  shutil  
			
		
	
		
			
				
					import  subprocess  
			
		
	
		
			
				
					import  threading  
			
		
	
		
			
				
					import  time  
			
		
	
		
			
				
					import  unittest  
			
		
	
		
			
				
					from  parameterized  import  parameterized  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -15,22 +14,24 @@ from common.params import Params 
			
		
	
		
			
				
					from  common . timeout  import  Timeout  
			
		
	
		
			
				
					from  selfdrive . hardware  import  EON ,  TICI  
			
		
	
		
			
				
					from  selfdrive . test . helpers  import  with_processes  
			
		
	
		
			
				
					from  selfdrive . loggerd . config  import  ROOT ,  CAMERA_FPS  
			
		
	
		
			
				
					from  selfdrive . loggerd . config  import  ROOT  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					# baseline file sizes for a 2s segment, in bytes  
			
		
	
		
			
				
					SEGMENT_LENGTH  =  2  
			
		
	
		
			
				
					FULL_SIZE  =  1253786  
			
		
	
		
			
				
					FULL_SIZE  =  1253786   # file size for a 2s segment in bytes   
			
		
	
		
			
				
					if  EON :  
			
		
	
		
			
				
					  CAMERAS  =  {   
			
		
	
		
			
				
					    " fcamera " :  FULL_SIZE ,   
			
		
	
		
			
				
					    " dcamera " :  770920 ,   
			
		
	
		
			
				
					    " qcamera " :  38533 ,   
			
		
	
		
			
				
					  }   
			
		
	
		
			
				
					  CAMERAS  =  [   
			
		
	
		
			
				
					    ( " fcamera.hevc  " ,  20 ,  FULL_SIZE ) ,   
			
		
	
		
			
				
					    ( " dcamera.hevc  " ,  10 ,  770920 ) ,   
			
		
	
		
			
				
					    ( " qcamera.ts  " ,  20 ,  38533 ) ,   
			
		
	
		
			
				
					  ]   
			
		
	
		
			
				
					else :  
			
		
	
		
			
				
					  CAMERAS  =  { f " { c } camera " :  FULL_SIZE  if  c != " q "  else  38533  for  c  in  [ " f " ,  " e " ,  " d " ,  " q " ] }   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					ALL_CAMERA_COMBINATIONS  =  [ ( cameras , )  for  cameras  in  [ CAMERAS ,  { k : CAMERAS [ k ]  for  k  in  CAMERAS  if  k != ' dcamera ' } ] ]  
			
		
	
		
			
				
					  CAMERAS  =  [   
			
		
	
		
			
				
					    ( " fcamera.hevc " ,  20 ,  FULL_SIZE ) ,   
			
		
	
		
			
				
					    ( " dcamera.hevc " ,  20 ,  FULL_SIZE ) ,   
			
		
	
		
			
				
					    ( " ecamera.hevc " ,  20 ,  FULL_SIZE ) ,   
			
		
	
		
			
				
					    ( " qcamera.ts " ,  20 ,  38533 ) ,   
			
		
	
		
			
				
					  ]   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					# we check frame count, so we don't have to be too strict on size  
			
		
	
		
			
				
					FILE_SIZE_TOLERANCE  =  0.5  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -60,11 +61,10 @@ class TestEncoder(unittest.TestCase): 
			
		
	
		
			
				
					    return  os . path . join ( ROOT ,  last_route )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  # TODO: this should run faster than real time   
			
		
	
		
			
				
					  @parameterized . expand ( ALL_CAMERA_COMBINATIONS )   
			
		
	
		
			
				
					  @with_processes ( [ ' camerad ' ,  ' sensord ' ,  ' loggerd ' ] )   
			
		
	
		
			
				
					  def  test_log_rotation ( self ,  cameras ) :   
			
		
	
		
			
				
					    print ( " checking targets: " ,  cameras )   
			
		
	
		
			
				
					    Params ( ) . put ( " RecordFront " ,  " 1 "  if  ' dcamera '  in  cameras  else  " 0 " )   
			
		
	
		
			
				
					  @parameterized . expand ( [ ( True ,  ) ,  ( False ,  ) ] )   
			
		
	
		
			
				
					  @with_processes ( [ ' camerad ' ,  ' sensord ' ,  ' loggerd ' ] ,  init_time = 3 )   
			
		
	
		
			
				
					  def  test_log_rotation ( self ,  record_front ) :   
			
		
	
		
			
				
					    Params ( ) . put ( " RecordFront " ,  str ( int ( record_front ) ) )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    num_segments  =  random . randint ( 80 ,  150 )   
			
		
	
		
			
				
					    if  " CI "  in  os . environ :   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -72,58 +72,45 @@ class TestEncoder(unittest.TestCase): 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    # wait for loggerd to make the dir for first segment   
			
		
	
		
			
				
					    route_prefix_path  =  None   
			
		
	
		
			
				
					    with  Timeout ( int ( SEGMENT_LENGTH * 2 ) ) :   
			
		
	
		
			
				
					    with  Timeout ( int ( SEGMENT_LENGTH * 3 ) ) :   
			
		
	
		
			
				
					      while  route_prefix_path  is  None :   
			
		
	
		
			
				
					        try :   
			
		
	
		
			
				
					          route_prefix_path  =  self . _get_latest_segment_path ( ) . rsplit ( " -- " ,  1 ) [ 0 ]   
			
		
	
		
			
				
					        except  Exception :   
			
		
	
		
			
				
					          time . sleep ( 0.1 )   
			
		
	
		
			
				
					          continue   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    def  check_seg ( i ) :   
			
		
	
		
			
				
					      # check each camera file size   
			
		
	
		
			
				
					      for  camera ,  size  in  cameras . items ( ) :   
			
		
	
		
			
				
					        ext  =  " ts "  if  camera == ' qcamera '  else  " hevc "   
			
		
	
		
			
				
					        file_path  =  f " { route_prefix_path } -- { i } / { camera } . { ext } "   
			
		
	
		
			
				
					      for  camera ,  fps ,  size  in  CAMERAS :   
			
		
	
		
			
				
					        if  not  record_front  and  " dcamera "  in  camera :   
			
		
	
		
			
				
					          continue   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        file_path  =  f " { route_prefix_path } -- { i } / { camera } "   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        # check file size   
			
		
	
		
			
				
					        self . assertTrue ( os . path . exists ( file_path ) ,  f " couldn ' t find  { file_path } " )   
			
		
	
		
			
				
					        self . assertTrue ( os . path . exists ( file_path ) )   
			
		
	
		
			
				
					        file_size  =  os . path . getsize ( file_path )   
			
		
	
		
			
				
					        self . assertTrue ( math . isclose ( file_size ,  size ,  rel_tol = FILE_SIZE_TOLERANCE ) ,   
			
		
	
		
			
				
					                        f " { camera }  failed size check: expected  { size } , got  { file_size } " )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        if  camera  ==  ' qcamera ' :   
			
		
	
		
			
				
					          continue   
			
		
	
		
			
				
					        self . assertTrue ( math . isclose ( file_size ,  size ,  rel_tol = FILE_SIZE_TOLERANCE ) )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        # TODO: this ffprobe call is really slow   
			
		
	
		
			
				
					        # check frame count   
			
		
	
		
			
				
					        cmd  =  f " ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames  \   
			
		
	
		
			
				
					               - of  default = nokey = 1 : noprint_wrappers = 1  { file_path } "   
			
		
	
		
			
				
					        expected_frames  =  SEGMENT_LENGTH  *  CAMERA_FPS  / /  2  if  ( EON  and  camera == ' dcamera ' )  else  SEGMENT_LENGTH  *  CAMERA_FPS   
			
		
	
		
			
				
					        frame_tolerance  =  1  if  ( EON  and  camera  ==  ' dcamera ' )  else  0   
			
		
	
		
			
				
					        frame_count  =  int ( subprocess . check_output ( cmd ,  shell = True ,  encoding = ' utf8 ' ) . strip ( ) )   
			
		
	
		
			
				
					        expected_frames  =  fps  *  SEGMENT_LENGTH   
			
		
	
		
			
				
					        frame_tolerance  =  1  if  ( EON  and  camera  ==  ' dcamera.hevc ' )  else  0   
			
		
	
		
			
				
					        probe  =  subprocess . check_output ( cmd ,  shell = True ,  encoding = ' utf8 ' )   
			
		
	
		
			
				
					        frame_count  =  int ( probe . split ( ' \n ' ) [ 0 ] . strip ( ) )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        self . assertTrue ( abs ( expected_frames  -  frame_count )  < =  frame_tolerance ,   
			
		
	
		
			
				
					                        f " { camera }  failed frame count check: expected  { expected_frames } , got  { frame_count } " )   
			
		
	
		
			
				
					      shutil . rmtree ( f " { route_prefix_path } -- { i } " )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    def  join ( ts ,  timeout ) :   
			
		
	
		
			
				
					      for  t  in  ts :   
			
		
	
		
			
				
					        t . join ( timeout )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    threads  =  [ ]   
			
		
	
		
			
				
					    for  i  in  trange ( num_segments ) :   
			
		
	
		
			
				
					      # poll for next segment   
			
		
	
		
			
				
					      with  Timeout ( int ( SEGMENT_LENGTH * 2 ) ,  error_msg = f " timed out waiting for segment  { i } " ) :   
			
		
	
		
			
				
					        while  int ( self . _get_latest_segment_path ( ) . rsplit ( " -- " ,  1 ) [ 1 ] )  < =  i :   
			
		
	
		
			
				
					          time . sleep ( 0.1 )   
			
		
	
		
			
				
					      t  =  threading . Thread ( target = check_seg ,  args = ( i ,  ) )   
			
		
	
		
			
				
					      t . start ( )   
			
		
	
		
			
				
					      threads . append ( t )   
			
		
	
		
			
				
					      join ( threads ,  0.1 )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    with  Timeout ( 20 ) :   
			
		
	
		
			
				
					      join ( threads ,  None )   
			
		
	
		
			
				
					      check_seg ( i )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					if  __name__  ==  " __main__ " :  
			
		
	
		
			
				
					  unittest . main ( )