mirror of
https://github.com/ultravioletrs/cocos.git
synced 2026-06-22 20:00:18 +00:00
4e8057f481
CI / ci (push) Has been cancelled
* Implement IMAMeasurements method in agentSDK and add corresponding unit tests Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add unit tests for NewIMAMeasurements command in CLI Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add error assertion for command execution in NewIMAMeasurements test Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Fix nil pointer dereference in Close method and update NewCreateVMCmd logic for manager client initialization Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Refactor file permission settings to use octal notation and improve cleanup handling in NewCreateVMCmd test Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add comprehensive unit tests for state machine functionality Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add mock implementation for Algorithm interface and corresponding test cases Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Refactor file permission settings to use octal notation in TestStopComputationIntegration Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Remove redundant reset test cases from TestStateMachine_Reset Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Fix race condition in action call verification in TestStateMachine_HandleEvent Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Enhance state machine with reset functionality and improve thread safety in event handling Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Improve error handling in state machine start function during tests Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Remove concurrent reset and send event test from state machine tests Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Remove error logging for Start function in transition tests Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add mock implementations for AgentService_IMAMeasurementsClient and Service Shutdown method; enhance progress tests for IMA measurements handling Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add comprehensive tests for FileStorage functionality including loading, saving, and concurrent access Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Enhance tests by adding dataset and algorithm hashes in handleRunReqChunks; improve error handling in TestFileStorage_ErrorHandling cleanup Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Enhance TestManagerClient_Process by adding new test cases for Agent state and Disconnect requests; update setupMocks to include grpcClient Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Fix graceful shutdown in gRPC server by adding nil checks for health and server instances Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Enhance TestAttestation by adding mock expectations for VTpmAttestation and Attestation methods; update service call to include platform parameter Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Enhance gRPC Server by adding synchronization for start/stop methods; prevent multiple starts and ensure graceful shutdown Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add unit tests for gRPC server methods including VM creation, removal, and info retrieval Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add tests for SEVSNP and TDX host capabilities; remove unused vsock code Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add a newline for better readability in vm_test.go Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add integration tests for gRPC client in cvm_test.go Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Remove unused vsock dependencies and add comprehensive unit tests for GCP attestation functions Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Skip GCP tests if credentials are not set Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add tests for error handling in attestation configuration and GCP commands Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Improve error handling in Azure VM test response writing Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Skip tests in GCP functions if credentials are not set Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add comprehensive unit tests for Azure attestation provider and verifier Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add unit tests for TPM functionality and improve error handling Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add comprehensive tests for attestation functionality and improve error handling Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add validation for teeNonce in TeeAttestation and implement comprehensive tests for provider methods Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Refactor error messages in TDX attestation tests for clarity Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Fix error message in TeeAttestation test for valid nonce case Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add MeasurementProvider mock and update mockery configuration Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add logging for product in parseUints and rename test functions for clarity Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Refactor TestSevsnpverify to reset configuration and improve error logging Signed-off-by: Sammy Oina <sammyoina@gmail.com> --------- Signed-off-by: Sammy Oina <sammyoina@gmail.com>
259 lines
5.7 KiB
Go
259 lines
5.7 KiB
Go
// Copyright (c) Ultraviolet
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
package agent
|
|
|
|
import (
|
|
"context"
|
|
sync "sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/ultravioletrs/cocos/agent/statemachine"
|
|
)
|
|
|
|
type MockState int
|
|
|
|
type MockEvent int
|
|
|
|
func (s MockState) String() string {
|
|
return []string{"State1", "State2", "State3"}[s]
|
|
}
|
|
|
|
func (e MockEvent) String() string {
|
|
return []string{"Event1", "Event2", "Event3"}[e]
|
|
}
|
|
|
|
const (
|
|
State1 MockState = iota
|
|
State2
|
|
State3
|
|
)
|
|
|
|
const (
|
|
Event1 MockEvent = iota
|
|
Event2
|
|
Event3
|
|
)
|
|
|
|
func TestNewStateMachine(t *testing.T) {
|
|
sm := statemachine.NewStateMachine(State1)
|
|
if sm == nil {
|
|
t.Fatal("NewStateMachine returned nil")
|
|
}
|
|
if sm.GetState() != State1 {
|
|
t.Errorf("Initial state not set correctly, got %v, want %v", sm.GetState(), State1)
|
|
}
|
|
}
|
|
|
|
func TestAddTransition(t *testing.T) {
|
|
sm := statemachine.NewStateMachine(State1)
|
|
sm.AddTransition(statemachine.Transition{From: State1, Event: Event1, To: State2})
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
|
|
defer cancel()
|
|
|
|
go func() {
|
|
if err := sm.Start(ctx); err != context.Canceled {
|
|
}
|
|
}()
|
|
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
sm.SendEvent(Event1)
|
|
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
if sm.GetState() != State2 {
|
|
t.Errorf("Transition not applied correctly, got state %v, want %v", sm.GetState(), State2)
|
|
}
|
|
}
|
|
|
|
func TestSetAction(t *testing.T) {
|
|
sm := statemachine.NewStateMachine(State1)
|
|
|
|
var wg sync.WaitGroup
|
|
wg.Add(1)
|
|
|
|
sm.SetAction(State2, func(s statemachine.State) {
|
|
defer wg.Done()
|
|
})
|
|
|
|
sm.AddTransition(statemachine.Transition{From: State1, Event: Event1, To: State2})
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 150*time.Millisecond)
|
|
defer cancel()
|
|
|
|
go func() {
|
|
if err := sm.Start(ctx); err != context.Canceled {
|
|
t.Errorf("Start returned error: %v", err)
|
|
}
|
|
}()
|
|
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
sm.SendEvent(Event1)
|
|
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
wg.Wait()
|
|
|
|
if ctx.Err() != nil {
|
|
t.Error("Action was not called within the expected time")
|
|
}
|
|
}
|
|
|
|
func TestInvalidTransition(t *testing.T) {
|
|
sm := statemachine.NewStateMachine(State1)
|
|
sm.AddTransition(statemachine.Transition{From: State1, Event: Event1, To: State2})
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
|
|
defer cancel()
|
|
|
|
errChan := make(chan error)
|
|
go func() {
|
|
errChan <- sm.Start(ctx)
|
|
}()
|
|
|
|
sm.SendEvent(Event2)
|
|
|
|
select {
|
|
case err := <-errChan:
|
|
if err == nil {
|
|
t.Errorf("Expected invalid transition error, got: %v", err)
|
|
}
|
|
case <-time.After(150 * time.Millisecond):
|
|
t.Error("Timeout waiting for invalid transition error")
|
|
}
|
|
}
|
|
|
|
func TestMultipleTransitions(t *testing.T) {
|
|
sm := statemachine.NewStateMachine(State1)
|
|
sm.AddTransition(statemachine.Transition{From: State1, Event: Event1, To: State2})
|
|
sm.AddTransition(statemachine.Transition{From: State2, Event: Event2, To: State3})
|
|
sm.AddTransition(statemachine.Transition{From: State3, Event: Event3, To: State1})
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
|
|
defer cancel()
|
|
|
|
go func() {
|
|
if err := sm.Start(ctx); err != context.Canceled {
|
|
}
|
|
}()
|
|
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
transitions := []struct {
|
|
event MockEvent
|
|
want MockState
|
|
}{
|
|
{Event1, State2},
|
|
{Event2, State3},
|
|
{Event3, State1},
|
|
}
|
|
|
|
for _, tt := range transitions {
|
|
sm.SendEvent(tt.event)
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
if sm.GetState() != tt.want {
|
|
t.Errorf("After event %v, got state %v, want %v", tt.event, sm.GetState(), tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestConcurrency(t *testing.T) {
|
|
sm := statemachine.NewStateMachine(State1)
|
|
sm.AddTransition(statemachine.Transition{From: State1, Event: Event1, To: State2})
|
|
sm.AddTransition(statemachine.Transition{From: State2, Event: Event2, To: State1})
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
|
|
defer cancel()
|
|
|
|
go func() {
|
|
if err := sm.Start(ctx); err == nil {
|
|
t.Errorf("Expected context error, got nil")
|
|
}
|
|
}()
|
|
|
|
for i := 0; i < 100; i++ {
|
|
go func() {
|
|
sm.SendEvent(Event1)
|
|
sm.SendEvent(Event2)
|
|
}()
|
|
}
|
|
|
|
time.Sleep(400 * time.Millisecond)
|
|
|
|
finalState := sm.GetState()
|
|
if finalState != State1 && finalState != State2 {
|
|
t.Errorf("Unexpected final state: %v", finalState)
|
|
}
|
|
}
|
|
|
|
func TestAgentEventString(t *testing.T) {
|
|
tests := []struct {
|
|
event AgentEvent
|
|
want string
|
|
}{
|
|
{Start, "Start"},
|
|
{ManifestReceived, "ManifestReceived"},
|
|
{AlgorithmReceived, "AlgorithmReceived"},
|
|
{DataReceived, "DataReceived"},
|
|
{RunComplete, "RunComplete"},
|
|
{ResultsConsumed, "ResultsConsumed"},
|
|
{RunFailed, "RunFailed"},
|
|
{AgentEvent(-1), "AgentEvent(-1)"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
if got := tt.event.String(); got != tt.want {
|
|
t.Errorf("AgentEvent.String() = %v, want %v", got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAgentStateString(t *testing.T) {
|
|
tests := []struct {
|
|
state AgentState
|
|
want string
|
|
}{
|
|
{Idle, "Idle"},
|
|
{ReceivingManifest, "ReceivingManifest"},
|
|
{ReceivingAlgorithm, "ReceivingAlgorithm"},
|
|
{ReceivingData, "ReceivingData"},
|
|
{Running, "Running"},
|
|
{ConsumingResults, "ConsumingResults"},
|
|
{Complete, "Complete"},
|
|
{Failed, "Failed"},
|
|
{AgentState(-1), "AgentState(-1)"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
if got := tt.state.String(); got != tt.want {
|
|
t.Errorf("AgentState.String() = %v, want %v", got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestStatusString(t *testing.T) {
|
|
tests := []struct {
|
|
status Status
|
|
want string
|
|
}{
|
|
{IdleState, "IdleState"},
|
|
{InProgress, "InProgress"},
|
|
{Ready, "Ready"},
|
|
{Completed, "Completed"},
|
|
{Terminated, "Terminated"},
|
|
{Warning, "Warning"},
|
|
{Starting, "Starting"},
|
|
{Status(uint8(8)), "Status(8)"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
if got := tt.status.String(); got != tt.want {
|
|
t.Errorf("Status.String() = %v, want %v", got, tt.want)
|
|
}
|
|
}
|
|
}
|