@@ -216,6 +216,9 @@ loop:
216216 if err := mgr .uploadCoverReport (); err != nil {
217217 mgr .Errorf ("failed to upload cover report: %v" , err )
218218 }
219+ if err := mgr .uploadProgramsWithCoverage (); err != nil {
220+ mgr .Errorf ("failed to upload programs with coverage: %v" , err )
221+ }
219222 if err := mgr .uploadCoverStat (fuzzingMinutesBeforeCover ); err != nil {
220223 mgr .Errorf ("failed to upload coverage stat: %v" , err )
221224 }
@@ -875,8 +878,8 @@ func (mgr *Manager) uploadCoverReport() error {
875878 return nil
876879}
877880
878- func (mgr * Manager ) uploadCoverStat ( fuzzingMinutes int ) error {
879- if ! mgr .managercfg .Cover || mgr . cfg . CoverPipelinePath == "" {
881+ func (mgr * Manager ) uploadJSONLToGCS ( mgrSrc , gcsDest string , f func (io. Writer , * json. Decoder , time. Time ) error ) error {
882+ if ! mgr .managercfg .Cover || gcsDest == "" {
880883 return nil
881884 }
882885
@@ -889,19 +892,16 @@ func (mgr *Manager) uploadCoverStat(fuzzingMinutes int) error {
889892 }
890893 defer buildSem .Signal ()
891894
892- // Coverage report generation consumes and caches lots of memory.
893- // In the syz-ci context report generation won't be used after this point,
894- // so tell manager to flush report generator.
895- resp , err := mgr .httpGET ("/cover?jsonl=1&flush=1" )
895+ resp , err := mgr .httpGET (mgrSrc )
896896 if err != nil {
897- return fmt .Errorf ("failed to httpGet /cover?jsonl=1 report : %w" , err )
897+ return fmt .Errorf ("failed to httpGet %s : %w" , mgrSrc , err )
898898 }
899899 defer resp .Body .Close ()
900900 if resp .StatusCode != http .StatusOK {
901901 sb := new (strings.Builder )
902902 io .Copy (sb , resp .Body )
903- return fmt .Errorf ("failed to GET /cover?jsonl=1 , httpStatus %d: %s" ,
904- resp .StatusCode , sb .String ())
903+ return fmt .Errorf ("failed to GET %s , httpStatus %d: %s" ,
904+ mgrSrc , resp .StatusCode , sb .String ())
905905 }
906906
907907 curTime := time .Now ()
@@ -910,12 +910,35 @@ func (mgr *Manager) uploadCoverStat(fuzzingMinutes int) error {
910910 go func () {
911911 decoder := json .NewDecoder (resp .Body )
912912 for decoder .More () {
913- var covInfo cover.CoverageInfo
914- if err := decoder .Decode (& covInfo ); err != nil {
915- pw .CloseWithError (fmt .Errorf ("failed to decode CoverageInfo: %w" , err ))
913+ if err := f (pw , decoder , curTime ); err != nil {
914+ pw .CloseWithError (fmt .Errorf ("callback: %w" , err ))
916915 return
917916 }
918- if err := cover .WriteCIJSONLine (pw , covInfo , cover.CIDetails {
917+ }
918+ pw .Close ()
919+ }()
920+ fileName := fmt .Sprintf ("%s/%s-%s-%d-%d.jsonl" ,
921+ mgr .mgrcfg .DashboardClient ,
922+ mgr .name , curTime .Format (time .DateOnly ),
923+ curTime .Hour (), curTime .Minute ())
924+ if err := mgr .uploadFile (mgr .cfg .CoverPipelinePath , fileName , pr , false ); err != nil {
925+ return fmt .Errorf ("failed to uploadFileGCS(): %w" , err )
926+ }
927+ return nil
928+ }
929+
930+ func (mgr * Manager ) uploadCoverStat (fuzzingMinutes int ) error {
931+ // Coverage report generation consumes and caches lots of memory.
932+ // In the syz-ci context report generation won't be used after this point,
933+ // so tell manager to flush report generator.
934+ if err := mgr .uploadJSONLToGCS ("/cover?jsonl=1&flush=1" ,
935+ mgr .cfg .CoverPipelinePath ,
936+ func (w io.Writer , dec * json.Decoder , curTime time.Time ) error {
937+ var covInfo cover.CoverageInfo
938+ if err := dec .Decode (& covInfo ); err != nil {
939+ return fmt .Errorf ("failed to decode CoverageInfo: %w" , err )
940+ }
941+ if err := cover .WriteCIJSONLine (w , covInfo , cover.CIDetails {
919942 Version : 1 ,
920943 Timestamp : curTime .Format (time .RFC3339Nano ),
921944 FuzzingMinutes : fuzzingMinutes ,
@@ -926,18 +949,31 @@ func (mgr *Manager) uploadCoverStat(fuzzingMinutes int) error {
926949 KernelBranch : mgr .lastBuild .KernelBranch ,
927950 KernelCommit : mgr .lastBuild .KernelCommit ,
928951 }); err != nil {
929- pw .CloseWithError (fmt .Errorf ("failed to write CIJSONLine: %w" , err ))
930- return
952+ return fmt .Errorf ("failed to write CIJSONLine: %w" , err )
931953 }
932- }
933- pw .Close ()
934- }()
935- fileName := fmt .Sprintf ("%s/%s-%s-%d-%d.jsonl" ,
936- mgr .mgrcfg .DashboardClient ,
937- mgr .name , curTime .Format (time .DateOnly ),
938- curTime .Hour (), curTime .Minute ())
939- if err := mgr .uploadFile (mgr .cfg .CoverPipelinePath , fileName , pr , false ); err != nil {
940- return fmt .Errorf ("failed to uploadFileGCS(): %w" , err )
954+ return nil
955+ }); err != nil {
956+ return fmt .Errorf ("mgr.uploadJSONLToGCS: %w" , err )
957+ }
958+ return nil
959+ }
960+
961+ func (mgr * Manager ) uploadProgramsWithCoverage () error {
962+ if err := mgr .uploadJSONLToGCS ("/coverprogs?jsonl=1" ,
963+ mgr .cfg .CoverProgramsPath ,
964+ func (w io.Writer , dec * json.Decoder , curTime time.Time ) error {
965+ var programCoverage cover.ProgramCoverage
966+ if err := dec .Decode (& programCoverage ); err != nil {
967+ return fmt .Errorf ("cover.ProgramCoverage: %w" , err )
968+ }
969+ programCoverage .Repo = mgr .lastBuild .KernelRepo
970+ programCoverage .Commit = mgr .lastBuild .KernelCommit
971+ if err := cover .WriteJSLine (w , & programCoverage ); err != nil {
972+ return fmt .Errorf ("cover.WriteJSLine: %w" , err )
973+ }
974+ return nil
975+ }); err != nil {
976+ return fmt .Errorf ("mgr.uploadJSONLToGCS: %w" , err )
941977 }
942978 return nil
943979}
0 commit comments