184 lines
7.0 KiB
Python
184 lines
7.0 KiB
Python
import unittest
|
|
from pathlib import Path
|
|
import os
|
|
|
|
from sia.entry.single_entry import SingleEntry
|
|
|
|
class SingleEntryTest(unittest.TestCase):
|
|
def setUp(self):
|
|
"""Set up test cases with fixed id"""
|
|
self.test_id = "test-id-1234"
|
|
self.work_dir = Path(os.getcwd()) # Use current directory for tests
|
|
|
|
# Create a temporary file for testing
|
|
self.test_filename = "test_output.txt"
|
|
self.cleanup_files()
|
|
|
|
def tearDown(self):
|
|
"""Clean up any test files"""
|
|
self.cleanup_files()
|
|
|
|
def cleanup_files(self):
|
|
"""Helper to remove test files"""
|
|
if os.path.exists(self.test_filename):
|
|
os.remove(self.test_filename)
|
|
|
|
def test_initialization(self):
|
|
"""Test entry initialization"""
|
|
script = "echo test"
|
|
entry = SingleEntry(self.test_id, self.work_dir, script, None, None)
|
|
|
|
self.assertEqual(entry.script, script)
|
|
self.assertEqual(entry.stdout, "")
|
|
self.assertEqual(entry.stderr, "")
|
|
self.assertIsNone(entry.exit_code)
|
|
self.assertEqual(entry.id, self.test_id)
|
|
self.assertFalse(entry.executed)
|
|
self.assertFalse(entry.timed_out)
|
|
|
|
def test_successful_execution(self):
|
|
"""Test successful script execution"""
|
|
script = "echo 'test'"
|
|
|
|
entry = SingleEntry(self.test_id, self.work_dir, script, None, None)
|
|
entry.update()
|
|
|
|
# Verify entry state
|
|
self.assertEqual(entry.stdout.strip(), "test")
|
|
self.assertEqual(entry.stderr, "")
|
|
self.assertEqual(entry.exit_code, 0)
|
|
self.assertTrue(entry.executed)
|
|
|
|
def test_failed_execution(self):
|
|
"""Test failed script execution with invalid command"""
|
|
entry = SingleEntry(self.test_id, self.work_dir, "nonexistentcommand", None, None)
|
|
entry.update()
|
|
|
|
# Verify entry state
|
|
self.assertEqual(entry.stdout, "")
|
|
self.assertTrue(len(entry.stderr) > 0) # Error message will vary by OS
|
|
self.assertNotEqual(entry.exit_code, 0) # Exit code will be non-zero
|
|
self.assertTrue(entry.executed)
|
|
|
|
def test_file_creation(self):
|
|
"""Test script that creates a file"""
|
|
script = f"echo 'test' > {self.test_filename}"
|
|
|
|
entry = SingleEntry(self.test_id, self.work_dir, script, None, None)
|
|
entry.update()
|
|
|
|
# Verify file was created and contains expected content
|
|
self.assertTrue(os.path.exists(self.test_filename))
|
|
with open(self.test_filename, 'r') as f:
|
|
content = f.read().strip()
|
|
self.assertEqual(content, "test")
|
|
|
|
def test_single_execution(self):
|
|
"""Test that script only executes once"""
|
|
script = f"echo 'test' >> {self.test_filename}"
|
|
|
|
entry = SingleEntry(self.test_id, self.work_dir, script, None, None)
|
|
|
|
# Run update multiple times
|
|
entry.update()
|
|
entry.update()
|
|
entry.update()
|
|
|
|
# Verify file only contains one line
|
|
with open(self.test_filename, 'r') as f:
|
|
lines = f.readlines()
|
|
self.assertEqual(len(lines), 1)
|
|
self.assertEqual(lines[0].strip(), "test")
|
|
|
|
def test_generate_context_before_execution(self):
|
|
"""Test XML context generation before execution"""
|
|
entry = SingleEntry(self.test_id, self.work_dir, "echo test", None, None)
|
|
element = entry.generate_context()
|
|
|
|
# Verify XML structure
|
|
self.assertEqual(element.tag, "single")
|
|
self.assertEqual(element.get("id"), self.test_id)
|
|
self.assertEqual(element.text, "echo test")
|
|
|
|
# Verify no output elements exist
|
|
self.assertIsNone(element.find("stdout"))
|
|
self.assertIsNone(element.find("stderr"))
|
|
self.assertIsNone(element.get("exit_code"))
|
|
|
|
def test_generate_context_after_execution(self):
|
|
"""Test XML context generation after execution"""
|
|
script = "echo 'test'"
|
|
|
|
entry = SingleEntry(self.test_id, self.work_dir, script, None, None)
|
|
entry.update()
|
|
element = entry.generate_context()
|
|
|
|
# Verify XML structure
|
|
self.assertEqual(element.tag, "single")
|
|
self.assertEqual(element.get("id"), self.test_id)
|
|
self.assertEqual(element.text, script)
|
|
|
|
# Get stdout and verify content
|
|
stdout_text = element.find("stdout").text
|
|
self.assertEqual(stdout_text, "test\n")
|
|
self.assertEqual(element.find("stderr").text, "")
|
|
self.assertEqual(element.get("exit_code"), "0")
|
|
|
|
def test_multiple_commands(self):
|
|
"""Test executing multiple commands in one script"""
|
|
script = f"echo 'first' > {self.test_filename} && echo 'second' >> {self.test_filename}"
|
|
|
|
entry = SingleEntry(self.test_id, self.work_dir, script, None, None)
|
|
entry.update()
|
|
|
|
# Verify file contains both lines
|
|
with open(self.test_filename, 'r') as f:
|
|
lines = f.readlines()
|
|
self.assertEqual(len(lines), 2)
|
|
self.assertEqual(lines[0].strip(), "first")
|
|
self.assertEqual(lines[1].strip(), "second")
|
|
|
|
def test_reset(self):
|
|
"""Test resetting the entry allows for reexecution"""
|
|
script = f"echo 'test' > {self.test_filename}"
|
|
|
|
entry = SingleEntry(self.test_id, self.work_dir, script, None, None)
|
|
entry.update()
|
|
|
|
# Verify initial execution
|
|
self.assertTrue(entry.executed)
|
|
self.assertTrue(os.path.exists(self.test_filename))
|
|
|
|
# Clean up file for retest
|
|
os.remove(self.test_filename)
|
|
|
|
# Reset and verify state
|
|
entry.reset()
|
|
self.assertFalse(entry.executed)
|
|
self.assertFalse(entry.timed_out)
|
|
self.assertEqual(entry.stdout, "")
|
|
self.assertEqual(entry.stderr, "")
|
|
self.assertIsNone(entry.exit_code)
|
|
|
|
# Run again and verify second execution works
|
|
entry.update()
|
|
self.assertTrue(entry.executed)
|
|
self.assertTrue(os.path.exists(self.test_filename))
|
|
|
|
def test_serialize(self):
|
|
"""Test serialization of the entry"""
|
|
script = "echo 'test'"
|
|
entry = SingleEntry(self.test_id, self.work_dir, script, None, None)
|
|
|
|
# Check initial serialized state
|
|
serialized = entry.serialize()
|
|
self.assertEqual(serialized["type"], "single")
|
|
self.assertEqual(serialized["id"], self.test_id)
|
|
self.assertEqual(serialized["script"], script)
|
|
self.assertEqual(serialized["executed"], False)
|
|
|
|
# Update and check updated serialized state
|
|
entry.update()
|
|
serialized = entry.serialize()
|
|
self.assertEqual(serialized["executed"], True)
|
|
self.assertEqual(serialized["exit_code"], 0) |