@@ -2,8 +2,11 @@ package workceptor_test
2
2
3
3
import (
4
4
"context"
5
+ "io"
6
+ "net/http"
5
7
"os"
6
8
"reflect"
9
+ "strings"
7
10
"sync"
8
11
"testing"
9
12
"time"
@@ -20,7 +23,9 @@ import (
20
23
"k8s.io/apimachinery/pkg/selection"
21
24
"k8s.io/apimachinery/pkg/watch"
22
25
"k8s.io/client-go/kubernetes"
26
+ "k8s.io/client-go/kubernetes/scheme"
23
27
"k8s.io/client-go/rest"
28
+ fakerest "k8s.io/client-go/rest/fake"
24
29
"k8s.io/client-go/tools/remotecommand"
25
30
)
26
31
@@ -139,7 +144,7 @@ func TestParseTime(t *testing.T) {
139
144
}
140
145
}
141
146
142
- func createKubernetesTestSetup (t * testing.T ) (workceptor.WorkUnit , * mock_workceptor.MockBaseWorkUnitForWorkUnit , * mock_workceptor.MockNetceptorForWorkceptor , * workceptor.Workceptor , * mock_workceptor.MockKubeAPIer , context.Context ) {
147
+ func createKubernetesTestSetup (t * testing.T ) (workceptor.WorkUnit , * mock_workceptor.MockBaseWorkUnitForWorkUnit , * mock_workceptor.MockNetceptorForWorkceptor , * workceptor.Workceptor , * mock_workceptor.MockKubeAPIer , * gomock. Controller , context.Context ) {
143
148
ctrl := gomock .NewController (t )
144
149
ctx := context .Background ()
145
150
@@ -157,7 +162,7 @@ func createKubernetesTestSetup(t *testing.T) (workceptor.WorkUnit, *mock_workcep
157
162
kubeConfig := workceptor.KubeWorkerCfg {AuthMethod : "incluster" }
158
163
ku := kubeConfig .NewkubeWorker (mockBaseWorkUnit , w , "" , "" , mockKubeAPI )
159
164
160
- return ku , mockBaseWorkUnit , mockNetceptor , w , mockKubeAPI , ctx
165
+ return ku , mockBaseWorkUnit , mockNetceptor , w , mockKubeAPI , ctrl , ctx
161
166
}
162
167
163
168
type hasTerm struct {
@@ -189,7 +194,7 @@ func (e *ex) StreamWithContext(_ context.Context, _ remotecommand.StreamOptions)
189
194
}
190
195
191
196
func TestKubeStart (t * testing.T ) {
192
- ku , mockbwu , mockNet , w , mockKubeAPI , ctx := createKubernetesTestSetup (t )
197
+ ku , mockbwu , mockNet , w , mockKubeAPI , _ , ctx := createKubernetesTestSetup (t )
193
198
194
199
startTestCases := []struct {
195
200
name string
@@ -423,3 +428,79 @@ func Test_IsCompatibleK8S(t *testing.T) {
423
428
})
424
429
}
425
430
}
431
+
432
+ func TestKubeLoggingWithReconnect (t * testing.T ) {
433
+ var stdinErr error
434
+ var stdoutErr error
435
+ ku , mockBaseWorkUnit , mockNetceptor , w , mockKubeAPI , ctrl , ctx := createKubernetesTestSetup (t )
436
+
437
+ kw := & workceptor.KubeUnit {
438
+ BaseWorkUnitForWorkUnit : mockBaseWorkUnit ,
439
+ }
440
+ tests := []struct {
441
+ name string
442
+ expectedCalls func ()
443
+ }{
444
+ {
445
+ name : "Kube error should be read" ,
446
+ expectedCalls : func () {
447
+ mockBaseWorkUnit .EXPECT ().UpdateBasicStatus (gomock .Any (), gomock .Any (), gomock .Any ()).AnyTimes ()
448
+ config := rest.Config {}
449
+ mockKubeAPI .EXPECT ().InClusterConfig ().Return (& config , nil )
450
+ mockBaseWorkUnit .EXPECT ().GetWorkceptor ().Return (w ).AnyTimes ()
451
+ clientset := kubernetes.Clientset {}
452
+ mockKubeAPI .EXPECT ().NewForConfig (gomock .Any ()).Return (& clientset , nil )
453
+ lock := & sync.RWMutex {}
454
+ mockBaseWorkUnit .EXPECT ().GetStatusLock ().Return (lock ).AnyTimes ()
455
+ mockBaseWorkUnit .EXPECT ().MonitorLocalStatus ().AnyTimes ()
456
+ mockBaseWorkUnit .EXPECT ().UnitDir ().Return ("TestDir2" ).AnyTimes ()
457
+ kubeExtraData := workceptor.KubeExtraData {}
458
+ status := workceptor.StatusFileData {ExtraData : & kubeExtraData }
459
+ mockBaseWorkUnit .EXPECT ().GetStatusWithoutExtraData ().Return (& status ).AnyTimes ()
460
+ mockBaseWorkUnit .EXPECT ().GetStatusCopy ().Return (status ).AnyTimes ()
461
+ mockBaseWorkUnit .EXPECT ().GetContext ().Return (ctx ).AnyTimes ()
462
+ pod := corev1.Pod {TypeMeta : metav1.TypeMeta {}, ObjectMeta : metav1.ObjectMeta {Name : "Test_Name" }, Spec : corev1.PodSpec {}, Status : corev1.PodStatus {}}
463
+ mockKubeAPI .EXPECT ().Create (gomock .Any (), gomock .Any (), gomock .Any (), gomock .Any (), gomock .Any ()).Return (& pod , nil ).AnyTimes ()
464
+ mockBaseWorkUnit .EXPECT ().UpdateFullStatus (gomock .Any ()).AnyTimes ()
465
+ field := hasTerm {}
466
+ mockKubeAPI .EXPECT ().OneTermEqualSelector (gomock .Any (), gomock .Any ()).Return (& field ).AnyTimes ()
467
+ ev := watch.Event {Object : & pod }
468
+ mockKubeAPI .EXPECT ().UntilWithSync (gomock .Any (), gomock .Any (), gomock .Any (), gomock .Any (), gomock .Any ()).Return (& ev , nil ).AnyTimes ()
469
+ mockKubeAPI .EXPECT ().Get (gomock .Any (), gomock .Any (), gomock .Any (), gomock .Any (), gomock .Any ()).Return (& pod , nil ).AnyTimes ()
470
+ req := fakerest.RESTClient {
471
+ Client : fakerest .CreateHTTPClient (func (request * http.Request ) (* http.Response , error ) {
472
+ resp := & http.Response {
473
+ StatusCode : http .StatusOK ,
474
+ Body : io .NopCloser (strings .NewReader ("2024-12-09T00:31:18.823849250Z HI\n kube error" )),
475
+ }
476
+
477
+ return resp , nil
478
+ }),
479
+ NegotiatedSerializer : scheme .Codecs .WithoutConversion (),
480
+ }
481
+ mockKubeAPI .EXPECT ().GetLogs (gomock .Any (), gomock .Any (), gomock .Any (), gomock .Any ()).Return (req .Request ()).AnyTimes ()
482
+ logger := logger .NewReceptorLogger ("" )
483
+ mockNetceptor .EXPECT ().GetLogger ().Return (logger ).AnyTimes ()
484
+ mockKubeAPI .EXPECT ().SubResource (gomock .Any (), gomock .Any (), gomock .Any ()).Return (req .Request ()).AnyTimes ()
485
+ exec := ex {}
486
+ mockKubeAPI .EXPECT ().NewSPDYExecutor (gomock .Any (), gomock .Any (), gomock .Any ()).Return (& exec , nil ).AnyTimes ()
487
+ },
488
+ },
489
+ }
490
+ for _ , tt := range tests {
491
+ t .Run (tt .name , func (t * testing.T ) {
492
+ tt .expectedCalls ()
493
+ ku .Start ()
494
+ kw .CreatePod (nil )
495
+ wg := & sync.WaitGroup {}
496
+ wg .Add (1 )
497
+ mockfilesystemer := mock_workceptor .NewMockFileSystemer (ctrl )
498
+ mockfilesystemer .EXPECT ().OpenFile (gomock .Any (), gomock .Any (), gomock .Any ()).Return (& os.File {}, nil )
499
+ stdout , _ := workceptor .NewStdoutWriter (mockfilesystemer , "" )
500
+ mockFileWC := mock_workceptor .NewMockFileWriteCloser (ctrl )
501
+ stdout .SetWriter (mockFileWC )
502
+ mockFileWC .EXPECT ().Write (gomock .AnyOf ([]byte ("HI\n " ), []byte (" kube error\n " ))).Return (0 , nil ).Times (2 )
503
+ kw .KubeLoggingWithReconnect (wg , stdout , & stdinErr , & stdoutErr )
504
+ })
505
+ }
506
+ }
0 commit comments