1
1
const fs = require ( 'fs' ) ;
2
2
const path = require ( 'path' ) ;
3
+ const zlib = require ( 'zlib' ) ;
4
+ const stream = require ( 'stream' ) ;
3
5
const FormData = require ( 'form-data-lite' ) ;
6
+ const ml = require ( 'mime-lite' )
4
7
const TestResult = require ( 'test-results-parser/src/models/TestResult' ) ;
5
8
const { BeatsApi } = require ( './beats.api' ) ;
6
9
const logger = require ( '../utils/logger' ) ;
@@ -23,12 +26,14 @@ class BeatsAttachments {
23
26
this . test_run_id = test_run_id ;
24
27
this . failed_test_cases = [ ] ;
25
28
this . attachments = [ ] ;
29
+ this . compressed_attachment_paths = [ ] ;
26
30
}
27
31
28
32
async upload ( ) {
29
33
this . #setAllFailedTestCases( ) ;
30
34
this . #setAttachments( ) ;
31
35
await this . #uploadAttachments( ) ;
36
+ this . #deleteCompressedAttachments( ) ;
32
37
}
33
38
34
39
#setAllFailedTestCases( ) {
@@ -67,17 +72,22 @@ class BeatsAttachments {
67
72
form . append ( 'test_run_id' , this . test_run_id ) ;
68
73
const file_images = [ ]
69
74
for ( const attachment of attachments_subset ) {
70
- const attachment_path = this . #getAttachmentFilePath( attachment ) ;
75
+ let attachment_path = this . #getAttachmentFilePath( attachment ) ;
71
76
if ( ! attachment_path ) {
72
77
logger . warn ( `⚠️ Unable to find attachment ${ attachment . path } ` ) ;
73
78
continue ;
74
79
}
80
+ attachment_path = await this . #compressAttachment( attachment_path ) ;
75
81
const stats = fs . statSync ( attachment_path ) ;
76
82
if ( stats . size > MAX_ATTACHMENT_SIZE ) {
77
83
logger . warn ( `⚠️ Attachment ${ attachment . path } is too big (${ stats . size } bytes). Allowed size is ${ MAX_ATTACHMENT_SIZE } bytes.` ) ;
78
84
continue ;
79
85
}
80
- form . append ( 'images' , fs . readFileSync ( attachment_path ) , { filename : path . basename ( attachment_path ) , filepath : attachment_path } ) ;
86
+ form . append ( 'images' , fs . readFileSync ( attachment_path ) , {
87
+ filename : path . basename ( attachment_path ) ,
88
+ filepath : attachment_path ,
89
+ contentType : ml . getType ( attachment . path ) ,
90
+ } ) ;
81
91
file_images . push ( {
82
92
file_name : attachment . name ,
83
93
file_path : attachment . path ,
@@ -123,7 +133,39 @@ class BeatsAttachments {
123
133
return null ;
124
134
}
125
135
136
+ /**
137
+ *
138
+ * @param {string } attachment_path
139
+ */
140
+ #compressAttachment( attachment_path ) {
141
+ return new Promise ( ( resolve , _ ) => {
142
+ console . log ( attachment_path )
143
+ if ( attachment_path . endsWith ( '.br' ) || attachment_path . endsWith ( '.gz' ) || attachment_path . endsWith ( '.zst' ) || attachment_path . endsWith ( '.zip' ) || attachment_path . endsWith ( '.7z' ) || attachment_path . endsWith ( '.png' ) || attachment_path . endsWith ( '.jpg' ) || attachment_path . endsWith ( '.jpeg' ) || attachment_path . endsWith ( '.svg' ) || attachment_path . endsWith ( '.gif' ) || attachment_path . endsWith ( '.webp' ) ) {
144
+ resolve ( attachment_path ) ;
145
+ return ;
146
+ }
147
+ const read_stream = fs . createReadStream ( attachment_path ) ;
148
+ const br = zlib . createBrotliCompress ( ) ;
126
149
150
+ const compressed_file_path = attachment_path + '.br' ;
151
+ const write_stream = fs . createWriteStream ( compressed_file_path ) ;
152
+ stream . pipeline ( read_stream , br , write_stream , ( err ) => {
153
+ if ( err ) {
154
+ resolve ( attachment_path ) ;
155
+ return ;
156
+ }
157
+ this . compressed_attachment_paths . push ( compressed_file_path ) ;
158
+ resolve ( compressed_file_path ) ;
159
+ return ;
160
+ } ) ;
161
+ } ) ;
162
+ }
163
+
164
+ #deleteCompressedAttachments( ) {
165
+ for ( const attachment_path of this . compressed_attachment_paths ) {
166
+ fs . unlinkSync ( attachment_path ) ;
167
+ }
168
+ }
127
169
128
170
}
129
171
0 commit comments