Files
Sammy Kerata Oina b44780df95
CI / lint (push) Has been cancelled
CI / test (agent) (push) Has been cancelled
CI / test (cli) (push) Has been cancelled
CI / test (cmd) (push) Has been cancelled
CI / test (internal) (push) Has been cancelled
CI / test (manager, true) (push) Has been cancelled
CI / test (pkg) (push) Has been cancelled
CI / upload-coverage (push) Has been cancelled
NOISSUE - Enhance OCI image extraction to return algorithm and requirements paths, and add deferred cleanup for temporary files (#586)
* feat: Enhance OCI image extraction to return algorithm and requirements paths, and add deferred cleanup for temporary files.

Signed-off-by: Sammy Oina <sammyoina@gmail.com>

* feat: implement deterministic zipping and enhance checksum verification for resources

Signed-off-by: Sammy Oina <sammyoina@gmail.com>

* feat: Update component build sources, add gRPC health checks to the CVM server, and refine algorithm argument handling and documentation.

Signed-off-by: Sammy Oina <sammyoina@gmail.com>

* docs: Update remote resources testing guide with `sudo` for KBS, algorithm result saving, `requirements.txt`, and `algo-args` for RVPS.

Signed-off-by: Sammy Oina <sammyoina@gmail.com>

* refactor: Explicitly ignore `stderr.Write` return values and add minor whitespace in tests.

Signed-off-by: Sammy Oina <sammyoina@gmail.com>

* test: add comprehensive error path and edge case tests for file, zip, OCI, and agent components.

Signed-off-by: Sammy Oina <sammyoina@gmail.com>

* feat: Add mutexes for thread-safe algorithm execution and expand recognized data file extensions to include common archive formats.

Signed-off-by: Sammy Oina <sammyoina@gmail.com>

* feat: Add OCI extraction tests for Python algorithms and multi-layer datasets, refactor algorithm execution for testability, and enhance algorithm stop and error handling tests.

Signed-off-by: Sammy Oina <sammyoina@gmail.com>

* test: Add error assertions to OCI extraction test helpers and remove an unused mock exec command.

Signed-off-by: Sammy Oina <sammyoina@gmail.com>

* test: Improve error handling test coverage for algorithm execution and OCI resource extraction.

Signed-off-by: Sammy Oina <sammyoina@gmail.com>

* fix: Improve algorithm process termination, enhance computation error handling, and add concurrency safety to agent service.

Signed-off-by: Sammy Oina <sammyoina@gmail.com>

---------

Signed-off-by: Sammy Oina <sammyoina@gmail.com>
2026-03-27 14:23:52 +01:00

214 lines
6.1 KiB
Go

// Copyright (c) Ultraviolet
// SPDX-License-Identifier: Apache-2.0
package internal
import (
"bytes"
"encoding/hex"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestCopyFile(t *testing.T) {
tempDir, err := os.MkdirTemp("", "copyfile_test")
if err != nil {
t.Fatalf("Failed to create temp dir: %v", err)
}
defer os.RemoveAll(tempDir)
srcPath := filepath.Join(tempDir, "source.txt")
content := []byte("Hello, World!")
if err := os.WriteFile(srcPath, content, 0o644); err != nil {
t.Fatalf("Failed to create source file: %v", err)
}
dstPath := filepath.Join(tempDir, "destination.txt")
if err := CopyFile(srcPath, dstPath); err != nil {
t.Fatalf("CopyFile failed: %v", err)
}
copiedContent, err := os.ReadFile(dstPath)
if err != nil {
t.Fatalf("Failed to read destination file: %v", err)
}
if !bytes.Equal(content, copiedContent) {
t.Errorf("Copied content does not match original. Got %s, want %s", copiedContent, content)
}
}
func TestCopyFile_NonExistentSource(t *testing.T) {
err := CopyFile("nonexistent.txt", "destination.txt")
if err == nil {
t.Error("CopyFile did not return an error for a nonexistent source file")
}
}
func TestDeleteFilesInDir(t *testing.T) {
tempDir, err := os.MkdirTemp("", "deletefiles_test")
if err != nil {
t.Fatalf("Failed to create temp dir: %v", err)
}
defer os.RemoveAll(tempDir)
filenames := []string{"file1.txt", "file2.txt", "file3.txt"}
for _, filename := range filenames {
filepath := filepath.Join(tempDir, filename)
if err := os.WriteFile(filepath, []byte("test"), 0o644); err != nil {
t.Fatalf("Failed to create test file: %v", err)
}
}
if err := DeleteFilesInDir(tempDir); err != nil {
t.Fatalf("DeleteFilesInDir failed: %v", err)
}
remainingFiles, err := os.ReadDir(tempDir)
if err != nil {
t.Fatalf("Failed to read directory: %v", err)
}
if len(remainingFiles) != 0 {
t.Errorf("Directory not empty after deletion. %d files remain", len(remainingFiles))
}
}
func TestChecksum(t *testing.T) {
tempDir, err := os.MkdirTemp("", "checksum_test")
if err != nil {
t.Fatalf("Failed to create temp dir: %v", err)
}
defer os.RemoveAll(tempDir)
filePath := filepath.Join(tempDir, "test.txt")
content := []byte("Hello, World!")
if err := os.WriteFile(filePath, content, 0o644); err != nil {
t.Fatalf("Failed to create test file: %v", err)
}
checksum, err := Checksum(filePath)
if err != nil {
t.Fatalf("Checksum failed: %v", err)
}
expectedChecksum, _ := hex.DecodeString("1af17a664e3fa8e419b8ba05c2a173169df76162a5a286e0c405b460d478f7ef")
if !bytes.Equal(checksum, expectedChecksum) {
t.Errorf("File checksum mismatch. Got %x, want %x", checksum, expectedChecksum)
}
dirPath := filepath.Join(tempDir, "testdir")
if err := os.Mkdir(dirPath, 0o755); err != nil {
t.Fatalf("Failed to create test directory: %v", err)
}
if err := os.WriteFile(filepath.Join(dirPath, "file1.txt"), []byte("File 1"), 0o644); err != nil {
t.Fatalf("Failed to create test file: %v", err)
}
if err := os.WriteFile(filepath.Join(dirPath, "file2.txt"), []byte("File 2"), 0o644); err != nil {
t.Fatalf("Failed to create test file: %v", err)
}
dirChecksum, err := Checksum(dirPath)
if err != nil {
t.Fatalf("Directory Checksum failed: %v", err)
}
if len(dirChecksum) != 32 { // SHA3-256 produces a 32-byte hash
t.Errorf("Unexpected directory checksum length. Got %d bytes, want 32 bytes", len(dirChecksum))
}
}
func TestChecksum_NonExistentFile(t *testing.T) {
_, err := Checksum("nonexistent.txt")
if err == nil {
t.Error("Checksum did not return an error for a nonexistent file")
}
}
func TestChecksumHex(t *testing.T) {
tempFile, err := os.CreateTemp("", "checksumhex_test")
if err != nil {
t.Fatalf("Failed to create temp file: %v", err)
}
defer os.Remove(tempFile.Name())
content := []byte("Hello, World!")
if _, err := tempFile.Write(content); err != nil {
t.Fatalf("Failed to write to test file: %v", err)
}
tempFile.Close()
checksumHex, err := ChecksumHex(tempFile.Name())
if err != nil {
t.Fatalf("ChecksumHex failed: %v", err)
}
expectedChecksumHex := "1af17a664e3fa8e419b8ba05c2a173169df76162a5a286e0c405b460d478f7ef"
if checksumHex != expectedChecksumHex {
t.Errorf("ChecksumHex mismatch. Got %s, want %s", checksumHex, expectedChecksumHex)
}
}
func TestCopyFile_ErrorPaths(t *testing.T) {
tempDir, err := os.MkdirTemp("", "copyfile_err_test")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
srcPath := filepath.Join(tempDir, "src.txt")
require.NoError(t, os.WriteFile(srcPath, []byte("test"), 0o644))
t.Run("destination folder creation failure", func(t *testing.T) {
// Create a file where a directory should be
blockedDir := filepath.Join(tempDir, "blocked_dir")
require.NoError(t, os.WriteFile(blockedDir, []byte("file"), 0o644))
dstPath := filepath.Join(blockedDir, "dst.txt")
err := CopyFile(srcPath, dstPath)
assert.Error(t, err)
})
t.Run("source file open failure", func(t *testing.T) {
err := CopyFile("/non/existent/src", filepath.Join(tempDir, "dst.txt"))
assert.Error(t, err)
})
}
func TestDeleteFilesInDir_ErrorPaths(t *testing.T) {
t.Run("non-existent directory", func(t *testing.T) {
err := DeleteFilesInDir("/non/existent/path")
// os.ReadDir on non-existent path returns error, but function returns nil
assert.NoError(t, err)
})
}
func TestDigest_ErrorPaths(t *testing.T) {
t.Run("non-existent file", func(t *testing.T) {
_, _, err := Digest("/non/existent/path")
assert.Error(t, err)
})
t.Run("directory digest failure", func(t *testing.T) {
// This happens if some file inside the directory cannot be read
tempDir, err := os.MkdirTemp("", "digest_err_test")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
blockedFile := filepath.Join(tempDir, "blocked.txt")
require.NoError(t, os.WriteFile(blockedFile, []byte("test"), 0o000)) // No permissions
_, _, err = Digest(tempDir)
// ZipDirectoryToMemory should fail due to permission error
assert.Error(t, err)
})
}
func TestChecksumHex_NonExistentFile(t *testing.T) {
_, err := ChecksumHex("nonexistent.txt")
if err == nil {
t.Error("ChecksumHex did not return an error for a nonexistent file")
}
}