mirror of
https://github.com/ultravioletrs/cocos.git
synced 2026-06-23 04:10:25 +00:00
8eb1fac9ad
* Refactor and update dependencies in the project - Updated go.sum to replace `github.com/absmach/magistrala` with `github.com/absmach/supermq` across various modules. - Removed VSock configuration from environment variables and QEMU arguments. - Updated QEMU configuration and related tests to remove references to guest CID and VSock. - Added new HTTP transport layer for API endpoints in the manager. - Introduced Prometheus monitoring configuration with alert rules and Alertmanager setup. - Updated service and VM interfaces to remove unused methods and references. - Refactored tests to align with the new structure and dependencies. Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add MaxVMs configuration and enforce limit on VM creation Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add comprehensive tests for HTTP transport handlers and endpoints Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add test case for exceeding maximum number of VMs in TestRun Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Improve error handling in TestHandlerWithCustomRouter to ensure response writing is checked Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Update dependencies to latest versions - Upgrade cel.dev/expr from v0.23.0 to v0.24.0 - Upgrade github.com/absmach/supermq from v0.16.0 to v0.17.0 - Upgrade github.com/cenkalti/backoff from v4.3.0 to v5.0.2 - Upgrade github.com/cncf/xds/go to v0.0.0-20250501225837-2ac532fd4443 - Upgrade github.com/go-chi/chi/v5 from v5.2.1 to v5.2.2 - Upgrade github.com/go-jose/go-jose/v3 from v3.0.3 to v3.0.4 - Upgrade github.com/gofrs/uuid/v5 from v5.3.0 to v5.3.2 - Upgrade github.com/prometheus/client_golang from v1.22.0 to v1.23.0 - Upgrade github.com/prometheus/client_model from v0.6.1 to v0.6.2 - Upgrade github.com/prometheus/common from v0.62.0 to v0.65.0 - Upgrade github.com/prometheus/procfs from v0.15.1 to v0.16.1 - Upgrade go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp from v0.60.0 to v0.62.0 - Upgrade go.opentelemetry.io/otel/exporters/otlp/otlptrace from v1.36.0 to v1.37.0 - Upgrade golang.org/x/crypto from v0.39.0 to v0.40.0 - Upgrade golang.org/x/sys from v0.33.0 to v0.34.0 - Upgrade golang.org/x/text from v0.26.0 to v0.27.0 - Upgrade golang.org/x/time from v0.11.0 to v0.12.0 - Upgrade google.golang.org/grpc from v1.73.0 to v1.74.2 Signed-off-by: Sammy Oina <sammyoina@gmail.com> --------- Signed-off-by: Sammy Oina <sammyoina@gmail.com>
637 lines
16 KiB
Go
637 lines
16 KiB
Go
// Copyright (c) Ultraviolet
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
package progressbar
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/absmach/supermq/pkg/errors"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/mock"
|
|
"github.com/ultravioletrs/cocos/agent"
|
|
"github.com/ultravioletrs/cocos/agent/mocks"
|
|
)
|
|
|
|
func TestNew(t *testing.T) {
|
|
pb := New(false)
|
|
assert.NotNil(t, pb)
|
|
assert.NotNil(t, pb.TerminalWidthFunc)
|
|
}
|
|
|
|
func TestSendAlgorithm(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
sendError error
|
|
closeRecvError error
|
|
err error
|
|
}{
|
|
{
|
|
name: "successful send and close",
|
|
sendError: nil,
|
|
closeRecvError: nil,
|
|
err: nil,
|
|
},
|
|
{
|
|
name: "send failure",
|
|
sendError: fmt.Errorf("network error during send"),
|
|
closeRecvError: nil,
|
|
err: fmt.Errorf("network error during send"),
|
|
},
|
|
{
|
|
name: "close and receive failure",
|
|
sendError: nil,
|
|
closeRecvError: fmt.Errorf("connection terminated"),
|
|
err: fmt.Errorf("connection terminated"),
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
pb := New(false)
|
|
|
|
algo, err := os.CreateTemp("", "test_algo")
|
|
assert.NoError(t, err)
|
|
req, err := os.CreateTemp("", "test_req")
|
|
assert.NoError(t, err)
|
|
|
|
_, err = algo.WriteString("test algorithm")
|
|
assert.NoError(t, err)
|
|
|
|
err = algo.Close()
|
|
assert.NoError(t, err)
|
|
|
|
algo, err = os.Open(algo.Name())
|
|
assert.NoError(t, err)
|
|
|
|
_, err = req.WriteString("test request")
|
|
assert.NoError(t, err)
|
|
|
|
err = req.Close()
|
|
assert.NoError(t, err)
|
|
|
|
req, err = os.Open(req.Name())
|
|
assert.NoError(t, err)
|
|
|
|
algoStream := new(mocks.AgentService_AlgoClient[agent.AlgoRequest, agent.AlgoResponse])
|
|
algoStream.On("Send", mock.Anything).Return(tc.sendError)
|
|
algoStream.On("CloseAndRecv").Return(&agent.AlgoResponse{}, tc.closeRecvError)
|
|
mockStream := &mockAlgoStream{stream: algoStream}
|
|
|
|
err = pb.SendAlgorithm("Test Algorithm", algo, req, mockStream.stream)
|
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("expected error: %v, got: %v", tc.err, err))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSendData(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
dataContent string
|
|
sendError error
|
|
closeRecvError error
|
|
err error
|
|
}{
|
|
{
|
|
name: "successful data send",
|
|
dataContent: "test data content",
|
|
sendError: nil,
|
|
closeRecvError: nil,
|
|
err: nil,
|
|
},
|
|
{
|
|
name: "send operation failure",
|
|
dataContent: "test data content",
|
|
sendError: fmt.Errorf("failed to send chunk"),
|
|
closeRecvError: nil,
|
|
err: fmt.Errorf("failed to send chunk"),
|
|
},
|
|
{
|
|
name: "close and receive failure",
|
|
dataContent: "test data content",
|
|
sendError: nil,
|
|
closeRecvError: fmt.Errorf("stream closed unexpectedly"),
|
|
err: fmt.Errorf("stream closed unexpectedly"),
|
|
},
|
|
{
|
|
name: "empty data content",
|
|
dataContent: "",
|
|
sendError: nil,
|
|
closeRecvError: nil,
|
|
err: nil,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
pb := New(false)
|
|
dataset, err := os.CreateTemp("", "test_dataset")
|
|
assert.NoError(t, err)
|
|
|
|
_, err = dataset.WriteString(tc.dataContent)
|
|
assert.NoError(t, err)
|
|
|
|
err = dataset.Close()
|
|
assert.NoError(t, err)
|
|
|
|
dataset, err = os.Open(dataset.Name())
|
|
assert.NoError(t, err)
|
|
|
|
dataStream := new(mocks.AgentService_DataClient[agent.DataRequest, agent.DataResponse])
|
|
dataStream.On("Send", mock.Anything).Return(tc.sendError)
|
|
dataStream.On("CloseAndRecv").Return(&agent.DataResponse{}, tc.closeRecvError)
|
|
mockStream := &mockDataStream{stream: dataStream}
|
|
|
|
err = pb.SendData("Test Data", "test.txt", dataset, mockStream.stream)
|
|
assert.True(t, errors.Contains(err, tc.err))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRenderProgressBarWithDifferentDescriptions(t *testing.T) {
|
|
testCases := []struct {
|
|
description string
|
|
expectedEmoji string
|
|
}{
|
|
{"Uploading algorithm", "🚀"},
|
|
{"Uploading data", "📦"},
|
|
{"Processing", "🚀"},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.description, func(t *testing.T) {
|
|
pb := &ProgressBar{
|
|
numberOfBytes: 100,
|
|
currentUploadedBytes: 50,
|
|
description: tc.description,
|
|
TerminalWidthFunc: func() (int, error) {
|
|
return 100, nil
|
|
},
|
|
}
|
|
|
|
var buf bytes.Buffer
|
|
oldStdout := os.Stdout
|
|
r, w, _ := os.Pipe()
|
|
os.Stdout = w
|
|
|
|
err := pb.renderProgressBar()
|
|
assert.NoError(t, err)
|
|
|
|
w.Close()
|
|
os.Stdout = oldStdout
|
|
|
|
_, err = io.Copy(&buf, r)
|
|
assert.NoError(t, err)
|
|
|
|
renderedBar := buf.String()
|
|
assert.Contains(t, renderedBar, tc.expectedEmoji)
|
|
assert.Contains(t, renderedBar, tc.description)
|
|
assert.Contains(t, renderedBar, "[0%]")
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRenderProgressBarWithMockedWidth(t *testing.T) {
|
|
oldStdout := os.Stdout
|
|
r, w, _ := os.Pipe()
|
|
os.Stdout = w
|
|
|
|
defer func() {
|
|
w.Close()
|
|
os.Stdout = oldStdout
|
|
}()
|
|
|
|
pb := &ProgressBar{
|
|
numberOfBytes: 100,
|
|
currentUploadedBytes: 0,
|
|
TerminalWidthFunc: func() (int, error) {
|
|
return 170, nil
|
|
},
|
|
}
|
|
|
|
err := pb.updateProgress(50)
|
|
assert.NoError(t, err)
|
|
err = pb.renderProgressBar()
|
|
assert.NoError(t, err)
|
|
|
|
err = w.Close()
|
|
assert.NoError(t, err)
|
|
|
|
var buf bytes.Buffer
|
|
_, err = io.Copy(&buf, r)
|
|
assert.NoError(t, err)
|
|
|
|
renderedBar := buf.String()
|
|
assert.Contains(t, renderedBar, "[50%]")
|
|
}
|
|
|
|
func TestClearProgressBar(t *testing.T) {
|
|
oldStdout := os.Stdout
|
|
r, w, _ := os.Pipe()
|
|
os.Stdout = w
|
|
|
|
defer func() {
|
|
w.Close()
|
|
os.Stdout = oldStdout
|
|
}()
|
|
|
|
pb := &ProgressBar{
|
|
numberOfBytes: 100,
|
|
currentUploadedBytes: 0,
|
|
maxWidth: 100,
|
|
TerminalWidthFunc: func() (int, error) {
|
|
return 50, nil
|
|
},
|
|
}
|
|
|
|
err := pb.updateProgress(50)
|
|
assert.NoError(t, err)
|
|
err = pb.renderProgressBar()
|
|
assert.NoError(t, err)
|
|
|
|
err = pb.clearProgressBar()
|
|
assert.NoError(t, err)
|
|
|
|
w.Close()
|
|
|
|
var buf bytes.Buffer
|
|
_, err = io.Copy(&buf, r)
|
|
assert.NoError(t, err)
|
|
|
|
clearedBar := buf.String()
|
|
expectedClear := "\r" + strings.Repeat(" ", pb.maxWidth) + "\r"
|
|
assert.Contains(t, clearedBar, expectedClear)
|
|
}
|
|
|
|
func TestReset(t *testing.T) {
|
|
pb := &ProgressBar{
|
|
numberOfBytes: 100,
|
|
currentUploadedBytes: 7,
|
|
maxWidth: 100,
|
|
description: "Test Upload",
|
|
}
|
|
|
|
description := ""
|
|
totalBytes := 0
|
|
pb.reset(description, totalBytes)
|
|
|
|
assert.Equal(t, 0, pb.currentUploadedBytes)
|
|
assert.Equal(t, 0, pb.currentUploadPercentage)
|
|
assert.Equal(t, totalBytes, pb.numberOfBytes)
|
|
assert.Equal(t, description, pb.description)
|
|
}
|
|
|
|
func TestUpdateProgress(t *testing.T) {
|
|
pb := &ProgressBar{
|
|
numberOfBytes: 100,
|
|
currentUploadPercentage: 0,
|
|
currentUploadedBytes: 0,
|
|
}
|
|
|
|
bytesRead := 25
|
|
err := pb.updateProgress(bytesRead)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 25, pb.currentUploadedBytes)
|
|
assert.Equal(t, 25, pb.currentUploadPercentage)
|
|
|
|
bytesRead = 50
|
|
err = pb.updateProgress(bytesRead)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 75, pb.currentUploadedBytes)
|
|
assert.Equal(t, 75, pb.currentUploadPercentage)
|
|
|
|
bytesRead = 50
|
|
err = pb.updateProgress(bytesRead)
|
|
assert.Error(t, err)
|
|
assert.EqualError(t, err, "progress update exceeds total bytes: attempted to add 50 bytes, but only 25 bytes remain")
|
|
|
|
// Ensure the progress does not exceed 100% after the error
|
|
assert.Equal(t, 75, pb.currentUploadedBytes)
|
|
assert.Equal(t, 75, pb.currentUploadPercentage)
|
|
}
|
|
|
|
type MockResultStream struct {
|
|
mock.Mock
|
|
agent.AgentService_ResultClient
|
|
}
|
|
|
|
func (m *MockResultStream) Recv() (*agent.ResultResponse, error) {
|
|
args := m.Called()
|
|
if res := args.Get(0); res != nil {
|
|
return res.(*agent.ResultResponse), args.Error(1)
|
|
}
|
|
return nil, args.Error(1)
|
|
}
|
|
|
|
type MockAttestationStream struct {
|
|
mock.Mock
|
|
agent.AgentService_AttestationClient
|
|
}
|
|
|
|
func (m *MockAttestationStream) Recv() (*agent.AttestationResponse, error) {
|
|
args := m.Called()
|
|
if res := args.Get(0); res != nil {
|
|
return res.(*agent.AttestationResponse), args.Error(1)
|
|
}
|
|
return nil, args.Error(1)
|
|
}
|
|
|
|
func TestReceiveResult(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
description string
|
|
totalSize int
|
|
chunks [][]byte
|
|
setupMock func(*MockResultStream)
|
|
wantResult []byte
|
|
wantErr error
|
|
}{
|
|
{
|
|
name: "successful single chunk receive",
|
|
description: "Receiving result",
|
|
totalSize: 5,
|
|
chunks: [][]byte{[]byte("hello")},
|
|
setupMock: func(m *MockResultStream) {
|
|
m.On("Recv").Return(&agent.ResultResponse{File: []byte("hello")}, nil).Once()
|
|
m.On("Recv").Return(nil, io.EOF).Once()
|
|
},
|
|
wantResult: []byte("hello"),
|
|
wantErr: nil,
|
|
},
|
|
{
|
|
name: "successful multi-chunk receive",
|
|
description: "Receiving result",
|
|
totalSize: 10,
|
|
chunks: [][]byte{[]byte("hello"), []byte("world")},
|
|
setupMock: func(m *MockResultStream) {
|
|
m.On("Recv").Return(&agent.ResultResponse{File: []byte("hello")}, nil).Once()
|
|
m.On("Recv").Return(&agent.ResultResponse{File: []byte("world")}, nil).Once()
|
|
m.On("Recv").Return(nil, io.EOF).Once()
|
|
},
|
|
wantResult: []byte("helloworld"),
|
|
wantErr: nil,
|
|
},
|
|
{
|
|
name: "stream error",
|
|
description: "Receiving result",
|
|
totalSize: 5,
|
|
setupMock: func(m *MockResultStream) {
|
|
m.On("Recv").Return(nil, errors.New("stream error")).Once()
|
|
},
|
|
wantResult: nil,
|
|
wantErr: errors.New("stream error"),
|
|
},
|
|
{
|
|
name: "empty result",
|
|
description: "Receiving result",
|
|
totalSize: 0,
|
|
setupMock: func(m *MockResultStream) {
|
|
m.On("Recv").Return(nil, io.EOF).Once()
|
|
},
|
|
wantResult: []byte{},
|
|
wantErr: nil,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
mockStream := &MockResultStream{}
|
|
tt.setupMock(mockStream)
|
|
|
|
p := New(true)
|
|
// Disable terminal width check for tests
|
|
p.TerminalWidthFunc = func() (int, error) { return 100, nil }
|
|
|
|
resultFile, err := os.CreateTemp("", "test_result")
|
|
assert.NoError(t, err)
|
|
|
|
t.Cleanup(func() {
|
|
os.Remove(resultFile.Name())
|
|
})
|
|
|
|
err = p.ReceiveResult(tt.description, tt.totalSize, mockStream, resultFile)
|
|
|
|
assert.NoError(t, resultFile.Close())
|
|
|
|
if tt.wantErr != nil {
|
|
assert.Error(t, err)
|
|
assert.Equal(t, tt.wantErr.Error(), err.Error())
|
|
} else {
|
|
assert.NoError(t, err)
|
|
|
|
result, err := os.ReadFile(resultFile.Name())
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, tt.wantResult, result)
|
|
}
|
|
|
|
mockStream.AssertExpectations(t)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReceiveAttestation(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
description string
|
|
totalSize int
|
|
chunks [][]byte
|
|
setupMock func(*MockAttestationStream)
|
|
wantResult []byte
|
|
wantErr error
|
|
}{
|
|
{
|
|
name: "successful single chunk receive",
|
|
description: "Receiving attestation",
|
|
totalSize: 5,
|
|
chunks: [][]byte{[]byte("proof")},
|
|
setupMock: func(m *MockAttestationStream) {
|
|
m.On("Recv").Return(&agent.AttestationResponse{File: []byte("proof")}, nil).Once()
|
|
m.On("Recv").Return(nil, io.EOF).Once()
|
|
},
|
|
wantResult: []byte("proof"),
|
|
wantErr: nil,
|
|
},
|
|
{
|
|
name: "successful multi-chunk receive",
|
|
description: "Receiving attestation",
|
|
totalSize: 15,
|
|
chunks: [][]byte{[]byte("proof"), []byte("signature")},
|
|
setupMock: func(m *MockAttestationStream) {
|
|
m.On("Recv").Return(&agent.AttestationResponse{File: []byte("proof")}, nil).Once()
|
|
m.On("Recv").Return(&agent.AttestationResponse{File: []byte("signature")}, nil).Once()
|
|
m.On("Recv").Return(nil, io.EOF).Once()
|
|
},
|
|
wantResult: []byte("proofsignature"),
|
|
wantErr: nil,
|
|
},
|
|
{
|
|
name: "stream error",
|
|
description: "Receiving attestation",
|
|
totalSize: 5,
|
|
setupMock: func(m *MockAttestationStream) {
|
|
m.On("Recv").Return(nil, errors.New("attestation error")).Once()
|
|
},
|
|
wantResult: nil,
|
|
wantErr: errors.New("attestation error"),
|
|
},
|
|
{
|
|
name: "size mismatch",
|
|
description: "Receiving attestation",
|
|
totalSize: 3,
|
|
chunks: [][]byte{[]byte("toolong")},
|
|
setupMock: func(m *MockAttestationStream) {
|
|
m.On("Recv").Return(&agent.AttestationResponse{File: []byte("toolong")}, nil).Once()
|
|
},
|
|
wantResult: nil,
|
|
wantErr: errors.New("progress update exceeds total bytes: attempted to add 7 bytes, but only 3 bytes remain"),
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
mockStream := &MockAttestationStream{}
|
|
tt.setupMock(mockStream)
|
|
|
|
p := New(true)
|
|
// Disable terminal width check for tests
|
|
p.TerminalWidthFunc = func() (int, error) { return 100, nil }
|
|
|
|
resultFile, err := os.CreateTemp("", "test_attestation")
|
|
assert.NoError(t, err)
|
|
|
|
t.Cleanup(func() {
|
|
os.Remove(resultFile.Name())
|
|
})
|
|
|
|
err = p.ReceiveAttestation(tt.description, tt.totalSize, mockStream, resultFile)
|
|
|
|
assert.NoError(t, resultFile.Close())
|
|
|
|
if tt.wantErr != nil {
|
|
assert.Error(t, err)
|
|
assert.Equal(t, tt.wantErr.Error(), err.Error())
|
|
} else {
|
|
assert.NoError(t, err)
|
|
|
|
result, err := os.ReadFile(resultFile.Name())
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, tt.wantResult, result)
|
|
}
|
|
|
|
mockStream.AssertExpectations(t)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReceiverIMAMeasurements(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
description string
|
|
totalSize int
|
|
chunks [][]byte
|
|
wantResult []byte
|
|
wantErr error
|
|
}{
|
|
{
|
|
name: "successful single chunk receive",
|
|
description: "Receiving IMA measurements",
|
|
totalSize: 20,
|
|
chunks: [][]byte{[]byte("12345678912345678999")},
|
|
wantResult: []byte("12345678912345678999"),
|
|
wantErr: nil,
|
|
},
|
|
{
|
|
name: "stream error",
|
|
description: "Receiving IMA measurements",
|
|
totalSize: 20,
|
|
chunks: [][]byte{[]byte("12345678912345678999")},
|
|
wantResult: nil,
|
|
wantErr: errors.New("stream error"),
|
|
},
|
|
{
|
|
name: "size mismatch",
|
|
description: "Receiving IMA measurements",
|
|
totalSize: 10,
|
|
chunks: [][]byte{[]byte("12345678912345678999")},
|
|
wantResult: nil,
|
|
wantErr: errors.New("progress update exceeds total bytes: attempted to add 20 bytes, but only 10 bytes remain"),
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
mockStream := new(mocks.AgentService_IMAMeasurementsClient[agent.IMAMeasurementsResponse])
|
|
|
|
p := New(true)
|
|
p.TerminalWidthFunc = func() (int, error) { return 100, nil }
|
|
|
|
resultFile, err := os.CreateTemp("", "test_ima_measurements")
|
|
assert.NoError(t, err)
|
|
|
|
t.Cleanup(func() {
|
|
os.Remove(resultFile.Name())
|
|
})
|
|
|
|
if tt.wantErr != nil {
|
|
mockStream.On("Recv").Return(nil, tt.wantErr).Once()
|
|
}
|
|
mockStream.On("Recv").Return(&agent.IMAMeasurementsResponse{Pcr10: []byte(tt.chunks[0]), File: []byte(tt.chunks[0])}, nil).Once()
|
|
mockStream.On("Recv").Return(nil, io.EOF).Once()
|
|
|
|
pcr10, err := p.ReceiveIMAMeasurements(tt.description, tt.totalSize, mockStream, resultFile)
|
|
|
|
assert.NoError(t, resultFile.Close())
|
|
|
|
if tt.wantErr != nil {
|
|
assert.Error(t, err)
|
|
assert.Equal(t, tt.wantErr.Error(), err.Error())
|
|
} else {
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, tt.wantResult, pcr10)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
type mockAlgoStream struct {
|
|
stream agent.AgentService_AlgoClient
|
|
sendCount int
|
|
closeAndRecvCalled bool
|
|
sendError error
|
|
closeRecvError error
|
|
}
|
|
|
|
func (m *mockAlgoStream) Send(*agent.AlgoRequest) error {
|
|
m.sendCount++
|
|
return m.sendError
|
|
}
|
|
|
|
func (m *mockAlgoStream) CloseAndRecv() (*agent.AlgoResponse, error) {
|
|
m.closeAndRecvCalled = true
|
|
return &agent.AlgoResponse{}, m.closeRecvError
|
|
}
|
|
|
|
type mockDataStream struct {
|
|
stream agent.AgentService_DataClient
|
|
sendCount int
|
|
closeAndRecvCalled bool
|
|
sendError error
|
|
closeRecvError error
|
|
}
|
|
|
|
func (m *mockDataStream) Send(*agent.DataRequest) error {
|
|
m.sendCount++
|
|
return m.sendError
|
|
}
|
|
|
|
func (m *mockDataStream) CloseAndRecv() (*agent.DataResponse, error) {
|
|
m.closeAndRecvCalled = true
|
|
return &agent.DataResponse{}, m.closeRecvError
|
|
}
|