4343import org .mockito .junit .jupiter .MockitoExtension ;
4444
4545import org .springframework .boot .buildpack .platform .docker .DockerApi .ContainerApi ;
46+ import org .springframework .boot .buildpack .platform .docker .DockerApi .Feature ;
4647import org .springframework .boot .buildpack .platform .docker .DockerApi .ImageApi ;
4748import org .springframework .boot .buildpack .platform .docker .DockerApi .SystemApi ;
4849import org .springframework .boot .buildpack .platform .docker .DockerApi .VolumeApi ;
8889@ ExtendWith ({ MockitoExtension .class , OutputCaptureExtension .class })
8990class DockerApiTests {
9091
91- private static final String API_URL = "/v" + DockerApi .API_VERSION ;
92+ private static final String API_URL = "/v" + DockerApi .PREFERRED_API_VERSION ;
9293
9394 public static final String PING_URL = "/_ping" ;
9495
9596 private static final String IMAGES_URL = API_URL + "/images" ;
9697
97- private static final String PLATFORM_IMAGES_URL = "/v" + DockerApi .PLATFORM_API_VERSION + "/images" ;
98-
99- private static final String PLATFORM_INSPECT_IMAGES_URL = "/v" + DockerApi .PLATFORM_INSPECT_API_VERSION + "/images" ;
100-
10198 private static final String CONTAINERS_URL = API_URL + "/containers" ;
10299
103- private static final String PLATFORM_CONTAINERS_URL = "/v" + DockerApi .PLATFORM_API_VERSION + "/containers" ;
104-
105100 private static final String VOLUMES_URL = API_URL + "/volumes" ;
106101
107102 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
@@ -249,12 +290,11 @@ void pullWithRegistryAuthPullsImageAndProducesEvents() throws Exception {
249290 @ Test
250291 void pullWithPlatformPullsImageAndProducesEvents () throws Exception {
251292 ImageReference reference = ImageReference .of ("gcr.io/paketo-buildpacks/builder:base" );
252- URI createUri = new URI (PLATFORM_IMAGES_URL
253- + " /create?fromImage=gcr.io%2Fpaketo-buildpacks%2Fbuilder%3Abase&platform=linux%2Farm64%2Fv1" );
254- URI imageUri = new URI (PLATFORM_INSPECT_IMAGES_URL + " /gcr.io/paketo-buildpacks/builder:base/json?platform="
293+ URI createUri = new URI (
294+ "/v1.49/images /create?fromImage=gcr.io%2Fpaketo-buildpacks%2Fbuilder%3Abase&platform=linux%2Farm64%2Fv1" );
295+ URI imageUri = new URI ("/v1.49/images /gcr.io/paketo-buildpacks/builder:base/json?platform="
255296 + ENCODED_LINUX_ARM64_PLATFORM_JSON );
256- given (http ().head (eq (new URI (PING_URL ))))
257- .willReturn (responseWithHeaders (new BasicHeader (DockerApi .API_VERSION_HEADER_NAME , "1.49" )));
297+ setVersion ("1.49" );
258298 given (http ().post (eq (createUri ), isNull ())).willReturn (responseOf ("pull-stream.json" ));
259299 given (http ().get (imageUri )).willReturn (responseOf ("type/image.json" ));
260300 Image image = this .api .pull (reference , LINUX_ARM64_PLATFORM , this .pullListener );
@@ -269,8 +309,7 @@ void pullWithPlatformPullsImageAndProducesEvents() throws Exception {
269309 void pullWithPlatformAndInsufficientApiVersionThrowsException () throws Exception {
270310 ImageReference reference = ImageReference .of ("gcr.io/paketo-buildpacks/builder:base" );
271311 ImagePlatform platform = ImagePlatform .of ("linux/arm64/v1" );
272- given (http ().head (eq (new URI (PING_URL )))).willReturn (
273- responseWithHeaders (new BasicHeader (DockerApi .API_VERSION_HEADER_NAME , DockerApi .API_VERSION )));
312+ setVersion ("1.24" );
274313 assertThatIllegalStateException ().isThrownBy (() -> this .api .pull (reference , platform , this .pullListener ))
275314 .withMessageContaining ("must be at least 1.41" )
276315 .withMessageContaining ("current API version is 1.24" );
@@ -414,10 +453,9 @@ void inspectInspectImage() throws Exception {
414453 @ Test
415454 void inspectWithPlatformWhenSupportedVersionInspectImage () throws Exception {
416455 ImageReference reference = ImageReference .of ("docker.io/paketobuildpacks/builder:base" );
417- URI imageUri = new URI (PLATFORM_INSPECT_IMAGES_URL
418- + "/docker.io/paketobuildpacks/builder:base/json?platform=" + ENCODED_LINUX_ARM64_PLATFORM_JSON );
419- given (http ().head (eq (new URI (PING_URL )))).willReturn (responseWithHeaders (
420- new BasicHeader (DockerApi .API_VERSION_HEADER_NAME , DockerApi .PLATFORM_INSPECT_API_VERSION )));
456+ URI imageUri = new URI ("/v1.49/images/docker.io/paketobuildpacks/builder:base/json?platform="
457+ + ENCODED_LINUX_ARM64_PLATFORM_JSON );
458+ setVersion ("1.49" );
421459 given (http ().get (imageUri )).willReturn (responseOf ("type/image-platform.json" ));
422460 Image image = this .api .inspect (reference , LINUX_ARM64_PLATFORM );
423461 assertThat (image .getArchitecture ()).isEqualTo ("arm64" );
@@ -427,9 +465,8 @@ void inspectWithPlatformWhenSupportedVersionInspectImage() throws Exception {
427465 @ Test
428466 void inspectWithPlatformWhenOldVersionInspectImage () throws Exception {
429467 ImageReference reference = ImageReference .of ("docker.io/paketobuildpacks/builder:base" );
430- URI imageUri = new URI (IMAGES_URL + "/docker.io/paketobuildpacks/builder:base/json" );
431- given (http ().head (eq (new URI (PING_URL )))).willReturn (responseWithHeaders (
432- new BasicHeader (DockerApi .API_VERSION_HEADER_NAME , DockerApi .PLATFORM_API_VERSION )));
468+ URI imageUri = new URI ("/v1.48/images/docker.io/paketobuildpacks/builder:base/json" );
469+ setVersion ("1.48" );
433470 given (http ().get (imageUri )).willReturn (responseOf ("type/image.json" ));
434471 Image image = this .api .inspect (reference , LINUX_ARM64_PLATFORM );
435472 assertThat (image .getArchitecture ()).isEqualTo ("amd64" );
@@ -597,7 +634,19 @@ void createWhenHasContentContainerWithContent() throws Exception {
597634
598635 @ Test
599636 void createWithPlatformCreatesContainer () throws Exception {
600- createWithPlatform ("1.41" );
637+ ImageReference imageReference = ImageReference .of ("ubuntu:bionic" );
638+ ContainerConfig config = ContainerConfig .of (imageReference , (update ) -> update .withCommand ("/bin/bash" ));
639+ ImagePlatform platform = ImagePlatform .of ("linux/arm64/v1" );
640+ setVersion ("1.41" );
641+ URI createUri = new URI ("/v1.41/containers/create?platform=linux%2Farm64%2Fv1" );
642+ given (http ().post (eq (createUri ), eq ("application/json" ), any ()))
643+ .willReturn (responseOf ("create-container-response.json" ));
644+ ContainerReference containerReference = this .api .create (config , platform );
645+ assertThat (containerReference ).hasToString ("e90e34656806" );
646+ then (http ()).should ().post (any (), any (), this .writer .capture ());
647+ ByteArrayOutputStream out = new ByteArrayOutputStream ();
648+ this .writer .getValue ().accept (out );
649+ assertThat (out .toByteArray ()).hasSize (config .toString ().length ());
601650 }
602651
603652 @ Test
@@ -609,11 +658,7 @@ private void createWithPlatform(@Nullable String apiVersion) throws IOException,
609658 ImageReference imageReference = ImageReference .of ("ubuntu:bionic" );
610659 ContainerConfig config = ContainerConfig .of (imageReference , (update ) -> update .withCommand ("/bin/bash" ));
611660 ImagePlatform platform = ImagePlatform .of ("linux/arm64/v1" );
612- if (apiVersion != null ) {
613- given (http ().head (eq (new URI (PING_URL ))))
614- .willReturn (responseWithHeaders (new BasicHeader (DockerApi .API_VERSION_HEADER_NAME , apiVersion )));
615- }
616- URI createUri = new URI (PLATFORM_CONTAINERS_URL + "/create?platform=linux%2Farm64%2Fv1" );
661+ URI createUri = new URI (CONTAINERS_URL + "/create?platform=linux%2Farm64%2Fv1" );
617662 given (http ().post (eq (createUri ), eq ("application/json" ), any ()))
618663 .willReturn (responseOf ("create-container-response.json" ));
619664 ContainerReference containerReference = this .api .create (config , platform );
@@ -629,8 +674,7 @@ void createWithPlatformAndKnownInsufficientApiVersionThrowsException() throws Ex
629674 ImageReference imageReference = ImageReference .of ("ubuntu:bionic" );
630675 ContainerConfig config = ContainerConfig .of (imageReference , (update ) -> update .withCommand ("/bin/bash" ));
631676 ImagePlatform platform = ImagePlatform .of ("linux/arm64/v1" );
632- given (http ().head (eq (new URI (PING_URL ))))
633- .willReturn (responseWithHeaders (new BasicHeader (DockerApi .API_VERSION_HEADER_NAME , "1.24" )));
677+ setVersion ("1.24" );
634678 assertThatIllegalStateException ().isThrownBy (() -> this .api .create (config , platform ))
635679 .withMessageContaining ("must be at least 1.41" )
636680 .withMessageContaining ("current API version is 1.24" );
0 commit comments