@@ -3,9 +3,11 @@ package k3s_test
33import (
44 "context"
55 "fmt"
6+ "regexp"
67 "testing"
78 "time"
89
10+ "github.com/containerd/platforms"
911 "github.com/stretchr/testify/require"
1012 corev1 "k8s.io/api/core/v1"
1113 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -39,17 +41,130 @@ func Test_LoadImages(t *testing.T) {
3941 provider , err := testcontainers .ProviderDocker .GetProvider ()
4042 require .NoError (t , err )
4143
44+ // This function only works for single architecture images
45+ // Forces the test to use a single-arch version of the image
46+ arch := platforms .DefaultSpec ().Architecture
47+ if platforms .DefaultSpec ().Variant != "" {
48+ arch += platforms .DefaultSpec ().Variant
49+ }
50+ nginxImg := arch + "/nginx"
51+
4252 // ensure nginx image is available locally
43- err = provider .PullImage (ctx , "nginx" )
53+ err = provider .PullImage (ctx , nginxImg )
4454 require .NoError (t , err )
4555
4656 t .Run ("Test load image not available" , func (t * testing.T ) {
4757 err := k3sContainer .LoadImages (ctx , "fake.registry/fake:non-existing" )
4858 require .Error (t , err )
4959 })
5060
61+ t .Run ("Test load image with wrong architecture" , func (t * testing.T ) {
62+ p , _ := platforms .Parse ("linux/s390x" )
63+ img := "nginx:mainline"
64+ err = provider .PullImageWithOpts (ctx , img , testcontainers .PullDockerImageWithPlatform (p ))
65+ require .NoError (t , err )
66+
67+ err := k3sContainer .LoadImages (ctx , img )
68+ require .Error (t , err )
69+ require .Regexp (t , "content digest .* not found" , err )
70+ })
71+
72+ t .Run ("Test load image in cluster" , func (t * testing.T ) {
73+ err := k3sContainer .LoadImages (ctx , nginxImg )
74+ require .NoError (t , err )
75+
76+ pod := & corev1.Pod {
77+ TypeMeta : metav1.TypeMeta {
78+ Kind : "Pod" ,
79+ APIVersion : "v1" ,
80+ },
81+ ObjectMeta : metav1.ObjectMeta {
82+ Name : "test-pod" ,
83+ },
84+ Spec : corev1.PodSpec {
85+ Containers : []corev1.Container {
86+ {
87+ Name : "nginx" ,
88+ Image : nginxImg ,
89+ ImagePullPolicy : corev1 .PullNever , // use image only if already present
90+ },
91+ },
92+ },
93+ }
94+
95+ _ , err = k8s .CoreV1 ().Pods ("default" ).Create (ctx , pod , metav1.CreateOptions {})
96+ require .NoError (t , err )
97+
98+ err = kwait .PollUntilContextCancel (ctx , time .Second , true , func (ctx context.Context ) (bool , error ) {
99+ state , err := getTestPodState (ctx , k8s )
100+ if err != nil {
101+ return false , err
102+ }
103+ if state .Terminated != nil {
104+ return false , fmt .Errorf ("pod terminated: %v" , state .Terminated )
105+ }
106+ return state .Running != nil , nil
107+ })
108+ require .NoError (t , err )
109+
110+ state , err := getTestPodState (ctx , k8s )
111+ require .NoError (t , err )
112+ require .NotNil (t , state .Running )
113+ })
114+ }
115+
116+ func Test_LoadImagesWithPlatform (t * testing.T ) {
117+ // Give up to three minutes to run this test
118+ ctx , cancel := context .WithDeadline (context .Background (), time .Now ().Add (3 * time .Minute ))
119+ defer cancel ()
120+
121+ k3sContainer , err := k3s .Run (ctx , "rancher/k3s:v1.27.1-k3s1" )
122+ testcontainers .CleanupContainer (t , k3sContainer )
123+ require .NoError (t , err )
124+
125+ kubeConfigYaml , err := k3sContainer .GetKubeConfig (ctx )
126+ require .NoError (t , err )
127+
128+ restcfg , err := clientcmd .RESTConfigFromKubeConfig (kubeConfigYaml )
129+ require .NoError (t , err )
130+
131+ k8s , err := kubernetes .NewForConfig (restcfg )
132+ require .NoError (t , err )
133+
134+ provider , err := testcontainers .ProviderDocker .GetProvider ()
135+ require .NoError (t , err )
136+
137+ // ensure nginx image is available locally
138+ err = provider .PullImage (ctx , "nginx" )
139+ require .NoError (t , err )
140+
141+ t .Run ("Test load image not available" , func (t * testing.T ) {
142+ p , _ := platforms .Parse ("linux/amd64" )
143+ err := k3sContainer .LoadImagesWithPlatform (ctx , []string {"fake.registry/fake:non-existing" }, & p )
144+ require .Error (t , err )
145+ })
146+
147+ t .Run ("Test load image with wrong architecture" , func (t * testing.T ) {
148+ pullPlatform , _ := platforms .Parse ("linux/s390x" )
149+ img := "nginx:mainline"
150+ err = provider .PullImageWithOpts (ctx , img , testcontainers .PullDockerImageWithPlatform (pullPlatform ))
151+ require .NoError (t , err )
152+
153+ loadPlatform , _ := platforms .Parse ("linux/amd64" )
154+ err := k3sContainer .LoadImagesWithPlatform (ctx , []string {img }, & loadPlatform )
155+ require .Error (t , err )
156+ expected := fmt .Sprintf (
157+ "image with reference %s was found but does not provide the specified platform (%s)" ,
158+ img ,
159+ platforms .Format (loadPlatform ),
160+ )
161+ require .Contains (t , err .Error (), expected )
162+ })
163+
51164 t .Run ("Test load image in cluster" , func (t * testing.T ) {
52- err := k3sContainer .LoadImages (ctx , "nginx" )
165+ p := platforms .DefaultSpec ()
166+ p .OS = "linux"
167+ err := k3sContainer .LoadImagesWithPlatform (ctx , []string {"nginx" }, & p )
53168 require .NoError (t , err )
54169
55170 pod := & corev1.Pod {
0 commit comments