4242import org .mockito .junit .jupiter .MockitoExtension ;
4343
4444import org .springframework .boot .buildpack .platform .docker .DockerApi .ContainerApi ;
45+ import org .springframework .boot .buildpack .platform .docker .DockerApi .Feature ;
4546import org .springframework .boot .buildpack .platform .docker .DockerApi .ImageApi ;
4647import org .springframework .boot .buildpack .platform .docker .DockerApi .SystemApi ;
4748import org .springframework .boot .buildpack .platform .docker .DockerApi .VolumeApi ;
8990@ ExtendWith ({ MockitoExtension .class , OutputCaptureExtension .class })
9091class DockerApiTests {
9192
92- private static final String API_URL = "/v" + DockerApi .API_VERSION ;
93+ private static final String API_URL = "/v" + DockerApi .PREFERRED_API_VERSION ;
9394
9495 public static final String PING_URL = "/_ping" ;
9596
9697 private static final String IMAGES_URL = API_URL + "/images" ;
9798
98- private static final String PLATFORM_IMAGES_URL = "/v" + DockerApi .PLATFORM_API_VERSION + "/images" ;
99-
100- private static final String PLATFORM_INSPECT_IMAGES_URL = "/v" + DockerApi .PLATFORM_INSPECT_API_VERSION + "/images" ;
101-
10299 private static final String CONTAINERS_URL = API_URL + "/containers" ;
103100
104- private static final String PLATFORM_CONTAINERS_URL = "/v" + DockerApi .PLATFORM_API_VERSION + "/containers" ;
105-
106101 private static final String VOLUMES_URL = API_URL + "/volumes" ;
107102
108103 private static final ImagePlatform LINUX_ARM64_PLATFORM = ImagePlatform .of ("linux/arm64/v1" );
@@ -175,6 +170,52 @@ void createDockerApi() {
175170 assertThat (api ).isNotNull ();
176171 }
177172
173+ @ Test
174+ void buildUrlWhenUnknownVersionUsesPreferredVersion () throws Exception {
175+ setVersion ("0.0" );
176+ assertThat (this .dockerApi .buildUrl (Feature .BASELINE , "/test" ))
177+ .isEqualTo (URI .create ("/v" + DockerApi .PREFERRED_API_VERSION + "/test" ));
178+ }
179+
180+ @ Test
181+ void buildUrlWhenVersionIsGreaterThanPreferredUsesPreferred () throws Exception {
182+ setVersion ("1000.0" );
183+ assertThat (this .dockerApi .buildUrl (Feature .BASELINE , "/test" ))
184+ .isEqualTo (URI .create ("/v" + DockerApi .PREFERRED_API_VERSION + "/test" ));
185+ }
186+
187+ @ Test
188+ void buildUrlWhenVersionIsEqualToPreferredUsesPreferred () throws Exception {
189+ setVersion (DockerApi .PREFERRED_API_VERSION .toString ());
190+ assertThat (this .dockerApi .buildUrl (Feature .BASELINE , "/test" ))
191+ .isEqualTo (URI .create ("/v" + DockerApi .PREFERRED_API_VERSION + "/test" ));
192+ }
193+
194+ @ Test
195+ void buildUrlWhenVersionIsLessThanPreferredAndGreaterThanMinimumUsesVersionVersion () throws Exception {
196+ setVersion ("1.48" );
197+ assertThat (this .dockerApi .buildUrl (Feature .BASELINE , "/test" )).isEqualTo (URI .create ("/v1.48/test" ));
198+ }
199+
200+ @ Test
201+ void buildUrlWhenVersionIsLessThanPreferredAndEqualToMinimumUsesVersionVersion () throws Exception {
202+ setVersion (Feature .BASELINE .minimumVersion ().toString ());
203+ assertThat (this .dockerApi .buildUrl (Feature .BASELINE , "/test" )).isEqualTo (URI .create ("/v1.24/test" ));
204+ }
205+
206+ @ Test
207+ void buildUrlWhenVersionIsLessThanMinimumThrowsException () throws Exception {
208+ setVersion ("1.23" );
209+ assertThatIllegalStateException ().isThrownBy (() -> this .dockerApi .buildUrl (Feature .BASELINE , "/test" ))
210+ .withMessage ("Docker API version must be at least 1.24 "
211+ + "to support this feature, but current API version is 1.23" );
212+ }
213+
214+ private void setVersion (String version ) throws IOException , URISyntaxException {
215+ given (http ().head (eq (new URI (PING_URL ))))
216+ .willReturn (responseWithHeaders (new BasicHeader (DockerApi .API_VERSION_HEADER_NAME , version )));
217+ }
218+
178219 @ Nested
179220 class ImageDockerApiTests {
180221
@@ -243,12 +284,11 @@ void pullWithRegistryAuthPullsImageAndProducesEvents() throws Exception {
243284 @ Test
244285 void pullWithPlatformPullsImageAndProducesEvents () throws Exception {
245286 ImageReference reference = ImageReference .of ("gcr.io/paketo-buildpacks/builder:base" );
246- URI createUri = new URI (PLATFORM_IMAGES_URL
247- + " /create?fromImage=gcr.io%2Fpaketo-buildpacks%2Fbuilder%3Abase&platform=linux%2Farm64%2Fv1" );
248- URI imageUri = new URI (PLATFORM_INSPECT_IMAGES_URL + " /gcr.io/paketo-buildpacks/builder:base/json?platform="
287+ URI createUri = new URI (
288+ "/v1.49/images /create?fromImage=gcr.io%2Fpaketo-buildpacks%2Fbuilder%3Abase&platform=linux%2Farm64%2Fv1" );
289+ URI imageUri = new URI ("/v1.49/images /gcr.io/paketo-buildpacks/builder:base/json?platform="
249290 + ENCODED_LINUX_ARM64_PLATFORM_JSON );
250- given (http ().head (eq (new URI (PING_URL ))))
251- .willReturn (responseWithHeaders (new BasicHeader (DockerApi .API_VERSION_HEADER_NAME , "1.49" )));
291+ setVersion ("1.49" );
252292 given (http ().post (eq (createUri ), isNull ())).willReturn (responseOf ("pull-stream.json" ));
253293 given (http ().get (imageUri )).willReturn (responseOf ("type/image.json" ));
254294 Image image = this .api .pull (reference , LINUX_ARM64_PLATFORM , this .pullListener );
@@ -263,8 +303,7 @@ void pullWithPlatformPullsImageAndProducesEvents() throws Exception {
263303 void pullWithPlatformAndInsufficientApiVersionThrowsException () throws Exception {
264304 ImageReference reference = ImageReference .of ("gcr.io/paketo-buildpacks/builder:base" );
265305 ImagePlatform platform = ImagePlatform .of ("linux/arm64/v1" );
266- given (http ().head (eq (new URI (PING_URL )))).willReturn (
267- responseWithHeaders (new BasicHeader (DockerApi .API_VERSION_HEADER_NAME , DockerApi .API_VERSION )));
306+ setVersion ("1.24" );
268307 assertThatIllegalStateException ().isThrownBy (() -> this .api .pull (reference , platform , this .pullListener ))
269308 .withMessageContaining ("must be at least 1.41" )
270309 .withMessageContaining ("current API version is 1.24" );
@@ -402,10 +441,9 @@ void inspectInspectImage() throws Exception {
402441 @ Test
403442 void inspectWithPlatformWhenSupportedVersionInspectImage () throws Exception {
404443 ImageReference reference = ImageReference .of ("docker.io/paketobuildpacks/builder:base" );
405- URI imageUri = new URI (PLATFORM_INSPECT_IMAGES_URL
406- + "/docker.io/paketobuildpacks/builder:base/json?platform=" + ENCODED_LINUX_ARM64_PLATFORM_JSON );
407- given (http ().head (eq (new URI (PING_URL )))).willReturn (responseWithHeaders (
408- new BasicHeader (DockerApi .API_VERSION_HEADER_NAME , DockerApi .PLATFORM_INSPECT_API_VERSION )));
444+ URI imageUri = new URI ("/v1.49/images/docker.io/paketobuildpacks/builder:base/json?platform="
445+ + ENCODED_LINUX_ARM64_PLATFORM_JSON );
446+ setVersion ("1.49" );
409447 given (http ().get (imageUri )).willReturn (responseOf ("type/image-platform.json" ));
410448 Image image = this .api .inspect (reference , LINUX_ARM64_PLATFORM );
411449 assertThat (image .getArchitecture ()).isEqualTo ("arm64" );
@@ -415,9 +453,8 @@ void inspectWithPlatformWhenSupportedVersionInspectImage() throws Exception {
415453 @ Test
416454 void inspectWithPlatformWhenOldVersionInspectImage () throws Exception {
417455 ImageReference reference = ImageReference .of ("docker.io/paketobuildpacks/builder:base" );
418- URI imageUri = new URI (IMAGES_URL + "/docker.io/paketobuildpacks/builder:base/json" );
419- given (http ().head (eq (new URI (PING_URL )))).willReturn (responseWithHeaders (
420- new BasicHeader (DockerApi .API_VERSION_HEADER_NAME , DockerApi .PLATFORM_API_VERSION )));
456+ URI imageUri = new URI ("/v1.48/images/docker.io/paketobuildpacks/builder:base/json" );
457+ setVersion ("1.48" );
421458 given (http ().get (imageUri )).willReturn (responseOf ("type/image.json" ));
422459 Image image = this .api .inspect (reference , LINUX_ARM64_PLATFORM );
423460 assertThat (image .getArchitecture ()).isEqualTo ("amd64" );
@@ -580,23 +617,27 @@ void createWhenHasContentContainerWithContent() throws Exception {
580617
581618 @ Test
582619 void createWithPlatformCreatesContainer () throws Exception {
583- createWithPlatform ("1.41" );
620+ ImageReference imageReference = ImageReference .of ("ubuntu:bionic" );
621+ ContainerConfig config = ContainerConfig .of (imageReference , (update ) -> update .withCommand ("/bin/bash" ));
622+ ImagePlatform platform = ImagePlatform .of ("linux/arm64/v1" );
623+ setVersion ("1.41" );
624+ URI createUri = new URI ("/v1.41/containers/create?platform=linux%2Farm64%2Fv1" );
625+ given (http ().post (eq (createUri ), eq ("application/json" ), any ()))
626+ .willReturn (responseOf ("create-container-response.json" ));
627+ ContainerReference containerReference = this .api .create (config , platform );
628+ assertThat (containerReference ).hasToString ("e90e34656806" );
629+ then (http ()).should ().post (any (), any (), this .writer .capture ());
630+ ByteArrayOutputStream out = new ByteArrayOutputStream ();
631+ this .writer .getValue ().accept (out );
632+ assertThat (out .toByteArray ()).hasSize (config .toString ().length ());
584633 }
585634
586635 @ Test
587636 void createWithPlatformAndUnknownApiVersionAttemptsCreate () throws Exception {
588- createWithPlatform (null );
589- }
590-
591- private void createWithPlatform (String apiVersion ) throws IOException , URISyntaxException {
592637 ImageReference imageReference = ImageReference .of ("ubuntu:bionic" );
593638 ContainerConfig config = ContainerConfig .of (imageReference , (update ) -> update .withCommand ("/bin/bash" ));
594639 ImagePlatform platform = ImagePlatform .of ("linux/arm64/v1" );
595- if (apiVersion != null ) {
596- given (http ().head (eq (new URI (PING_URL ))))
597- .willReturn (responseWithHeaders (new BasicHeader (DockerApi .API_VERSION_HEADER_NAME , apiVersion )));
598- }
599- URI createUri = new URI (PLATFORM_CONTAINERS_URL + "/create?platform=linux%2Farm64%2Fv1" );
640+ URI createUri = new URI (CONTAINERS_URL + "/create?platform=linux%2Farm64%2Fv1" );
600641 given (http ().post (eq (createUri ), eq ("application/json" ), any ()))
601642 .willReturn (responseOf ("create-container-response.json" ));
602643 ContainerReference containerReference = this .api .create (config , platform );
@@ -612,8 +653,7 @@ void createWithPlatformAndKnownInsufficientApiVersionThrowsException() throws Ex
612653 ImageReference imageReference = ImageReference .of ("ubuntu:bionic" );
613654 ContainerConfig config = ContainerConfig .of (imageReference , (update ) -> update .withCommand ("/bin/bash" ));
614655 ImagePlatform platform = ImagePlatform .of ("linux/arm64/v1" );
615- given (http ().head (eq (new URI (PING_URL ))))
616- .willReturn (responseWithHeaders (new BasicHeader (DockerApi .API_VERSION_HEADER_NAME , "1.24" )));
656+ setVersion ("1.24" );
617657 assertThatIllegalStateException ().isThrownBy (() -> this .api .create (config , platform ))
618658 .withMessageContaining ("must be at least 1.41" )
619659 .withMessageContaining ("current API version is 1.24" );
0 commit comments