16
16
* specific language governing permissions and limitations
17
17
* under the License.
18
18
*/
19
+ use flate2:: read:: GzDecoder ;
20
+ use globset:: Glob ;
19
21
use io:: Write ;
20
- use reqwest:: header:: { HeaderMap , HeaderValue , AUTHORIZATION } ;
21
- use serde:: Deserialize ;
22
- use std:: { error:: Error as StdError , fmt:: Formatter , fs, fs:: File , io, path:: PathBuf } ;
23
-
24
- struct YamlTestSuite {
25
- dir : String ,
26
- branch : String ,
27
- url : String ,
28
- }
29
-
30
- #[ derive( Deserialize , Debug ) ]
31
- struct Links {
32
- #[ serde( rename = "self" ) ]
33
- self_link : String ,
34
- git : String ,
35
- html : String ,
36
- }
37
-
38
- #[ derive( Deserialize , Debug ) ]
39
- struct GitHubContent {
40
- name : String ,
41
- path : String ,
42
- sha : String ,
43
- size : i32 ,
44
- url : String ,
45
- html_url : String ,
46
- git_url : String ,
47
- download_url : Option < String > ,
48
- #[ serde( rename = "type" ) ]
49
- ty : String ,
50
- #[ serde( rename = "_links" ) ]
51
- links : Links ,
52
- }
22
+ use reqwest:: {
23
+ header:: { HeaderMap , HeaderValue , USER_AGENT } ,
24
+ Response ,
25
+ } ;
26
+ use std:: { fs, fs:: File , io, path:: PathBuf } ;
27
+ use tar:: { Archive , Entry } ;
53
28
54
29
/// Downloads the yaml tests if not already downloaded
55
- pub fn download_test_suites (
56
- token : & str ,
57
- branch : & str ,
58
- download_dir : & PathBuf ,
59
- ) -> Result < ( ) , failure:: Error > {
30
+ pub fn download_test_suites ( branch : & str , download_dir : & PathBuf ) -> Result < ( ) , failure:: Error > {
60
31
let mut last_downloaded_version = download_dir. clone ( ) ;
61
32
last_downloaded_version. push ( "last_downloaded_version" ) ;
62
33
if last_downloaded_version. exists ( ) {
63
34
let version = fs:: read_to_string ( & last_downloaded_version)
64
35
. expect ( "Unable to read last_downloaded_version of yaml tests" ) ;
65
36
if version == branch {
66
- info ! ( "yaml tests for branch {} already downloaded " , branch) ;
37
+ info ! ( "Already downloaded yaml tests from {} " , branch) ;
67
38
return Ok ( ( ) ) ;
68
39
}
69
40
}
70
41
71
- let test_suite_map = [
72
- ( "oss" . to_string ( ) , "https://api.github.com/repos/elastic/elasticsearch/contents/rest-api-spec/src/main/resources/rest-api-spec/test" . to_string ( ) ) ,
73
- ( "xpack" . to_string ( ) , "https://api.github.com/repos/elastic/elasticsearch/contents/x-pack/plugin/src/test/resources/rest-api-spec/test" . to_string ( ) ) ] ;
74
-
75
- let test_suites: Vec < YamlTestSuite > = test_suite_map
76
- . iter ( )
77
- . map ( |( dir, template_url) | {
78
- let url = format ! ( "{}?ref={}" , template_url, branch) ;
79
- YamlTestSuite {
80
- dir : dir. to_string ( ) ,
81
- branch : branch. to_string ( ) ,
82
- url,
83
- }
84
- } )
85
- . collect ( ) ;
86
-
42
+ info ! ( "Downloading yaml tests from {}" , branch) ;
43
+ let url = format ! (
44
+ "https://api.github.com/repos/elastic/elasticsearch/tarball/{}" ,
45
+ branch
46
+ ) ;
87
47
let mut headers = HeaderMap :: new ( ) ;
88
- let token_value = format ! ( "token {}" , token) ;
89
- headers. append ( AUTHORIZATION , HeaderValue :: from_str ( & token_value) ?) ;
48
+ headers. append (
49
+ USER_AGENT ,
50
+ HeaderValue :: from_str ( "elasticsearch-rs/yaml_test_runner" ) ?,
51
+ ) ;
90
52
let client = reqwest:: ClientBuilder :: new ( )
91
53
. default_headers ( headers)
92
54
. build ( )
93
55
. unwrap ( ) ;
94
56
95
- // delete existing yaml tests
96
- if download_dir. exists ( ) {
97
- fs:: remove_dir_all ( & download_dir) ?;
98
- }
99
-
100
- fs:: create_dir_all ( download_dir) ?;
101
-
102
- for suite in test_suites {
103
- download_tests ( & client, & suite, & download_dir) ?;
57
+ let response = client. get ( & url) . send ( ) ?;
58
+ let tar = GzDecoder :: new ( response) ;
59
+ let mut archive = Archive :: new ( tar) ;
60
+
61
+ let oss_test = Glob :: new ( "**/rest-api-spec/src/main/resources/rest-api-spec/test/**/*.yml" ) ?
62
+ . compile_matcher ( ) ;
63
+ let xpack_test = Glob :: new ( "**/x-pack/plugin/src/test/resources/rest-api-spec/test/**/*.yml" ) ?
64
+ . compile_matcher ( ) ;
65
+
66
+ for entry in archive. entries ( ) ? {
67
+ let file = entry?;
68
+ let path = file. path ( ) ?;
69
+ if oss_test. is_match ( & path) {
70
+ write_test_file ( download_dir, "oss" , file) ?;
71
+ } else if xpack_test. is_match ( & path) {
72
+ write_test_file ( download_dir, "xpack" , file) ?;
73
+ }
104
74
}
105
75
76
+ info ! ( "Downloaded yaml tests from {}" , & branch) ;
106
77
File :: create ( last_downloaded_version)
107
78
. expect ( "failed to create last_downloaded_version file" )
108
79
. write_all ( branch. as_bytes ( ) )
@@ -111,115 +82,25 @@ pub fn download_test_suites(
111
82
Ok ( ( ) )
112
83
}
113
84
114
- fn download_tests (
115
- client : & reqwest:: Client ,
116
- suite : & YamlTestSuite ,
85
+ fn write_test_file (
117
86
download_dir : & PathBuf ,
118
- ) -> Result < ( ) , DownloadError > {
119
- let suite_dir = {
120
- let mut d = download_dir. clone ( ) ;
121
- d. push ( & suite. dir ) ;
122
- d
87
+ suite_dir : & str ,
88
+ mut entry : Entry < GzDecoder < Response > > ,
89
+ ) -> Result < ( ) , failure:: Error > {
90
+ let path = entry. path ( ) ?;
91
+
92
+ let mut dir = {
93
+ let mut dir = download_dir. clone ( ) ;
94
+ dir. push ( suite_dir) ;
95
+ let parent = path. parent ( ) . unwrap ( ) . file_name ( ) . unwrap ( ) ;
96
+ dir. push ( parent) ;
97
+ dir
123
98
} ;
124
99
125
- fs:: create_dir_all ( & suite_dir) ?;
126
- info ! ( "Downloading {} tests from {}" , & suite. dir, & suite. branch) ;
127
- download ( client, & suite. url , & suite_dir) ?;
128
- info ! (
129
- "Done downloading {} tests from {}" ,
130
- & suite. dir, & suite. branch
131
- ) ;
100
+ fs:: create_dir_all ( & dir) ?;
101
+ dir. push ( path. file_name ( ) . unwrap ( ) ) ;
102
+ let mut file = File :: create ( & dir) ?;
103
+ io:: copy ( & mut entry, & mut file) ?;
132
104
133
105
Ok ( ( ) )
134
106
}
135
-
136
- fn download (
137
- client : & reqwest:: Client ,
138
- url : & str ,
139
- download_dir : & PathBuf ,
140
- ) -> Result < ( ) , DownloadError > {
141
- let mut response = client. get ( url) . send ( ) ?;
142
-
143
- let remaining_rate_limit: i32 = response
144
- . headers ( )
145
- . get ( "X-RateLimit-Remaining" )
146
- . unwrap ( )
147
- . to_str ( )
148
- . unwrap ( )
149
- . parse ( )
150
- . unwrap ( ) ;
151
-
152
- if remaining_rate_limit < 10 {
153
- warn ! ( "Remaining rate limit: {}" , remaining_rate_limit) ;
154
- }
155
-
156
- let contents: Vec < GitHubContent > = response. json ( ) ?;
157
- for content in contents {
158
- let content_path = {
159
- let mut d = download_dir. clone ( ) ;
160
- d. push ( & content. name ) ;
161
- d
162
- } ;
163
-
164
- match content. ty . as_str ( ) {
165
- "file" => {
166
- let mut file = File :: create ( content_path) ?;
167
- // no need to send the token for downloading content
168
- let mut file_response = reqwest:: get ( & content. download_url . unwrap ( ) ) ?;
169
- io:: copy ( & mut file_response, & mut file) ?;
170
- }
171
- "dir" => {
172
- fs:: create_dir_all ( & content_path) ?;
173
- download ( client, & content. url , & content_path) ?;
174
- }
175
- t => {
176
- return Err ( DownloadError :: InvalidType ( format ! (
177
- "Unexpected GitHub content type: {}" ,
178
- t
179
- ) ) )
180
- }
181
- }
182
- }
183
-
184
- Ok ( ( ) )
185
- }
186
-
187
- #[ derive( Debug ) ]
188
- pub enum DownloadError {
189
- IoErr ( io:: Error ) ,
190
- HttpError ( reqwest:: Error ) ,
191
- InvalidType ( String ) ,
192
- }
193
-
194
- impl std:: fmt:: Display for DownloadError {
195
- fn fmt ( & self , f : & mut Formatter < ' _ > ) -> Result < ( ) , std:: fmt:: Error > {
196
- match self {
197
- DownloadError :: IoErr ( err) => write ! ( f, "IoErr {}" , err) ,
198
- DownloadError :: HttpError ( err) => write ! ( f, "HttpError {}" , err) ,
199
- DownloadError :: InvalidType ( s) => write ! ( f, "InvalidType {}" , s) ,
200
- }
201
- }
202
- }
203
-
204
- impl StdError for DownloadError {
205
- #[ allow( warnings) ]
206
- fn description ( & self ) -> & str {
207
- match self {
208
- DownloadError :: IoErr ( err) => err. description ( ) ,
209
- DownloadError :: HttpError ( err) => err. description ( ) ,
210
- DownloadError :: InvalidType ( s) => s. as_ref ( ) ,
211
- }
212
- }
213
- }
214
-
215
- impl From < io:: Error > for DownloadError {
216
- fn from ( e : io:: Error ) -> Self {
217
- DownloadError :: IoErr ( e)
218
- }
219
- }
220
-
221
- impl From < reqwest:: Error > for DownloadError {
222
- fn from ( e : reqwest:: Error ) -> Self {
223
- DownloadError :: HttpError ( e)
224
- }
225
- }
0 commit comments