diff --git a/dockerimg/sshtheater_test.go b/dockerimg/sshtheater_test.go
new file mode 100644
index 0000000..952ce13
--- /dev/null
+++ b/dockerimg/sshtheater_test.go
@@ -0,0 +1,644 @@
+package dockerimg
+
+import (
+	"bytes"
+	"crypto/rand"
+	"crypto/rsa"
+	"fmt"
+	"io/fs"
+	"os"
+	"path/filepath"
+	"strings"
+	"testing"
+
+	"golang.org/x/crypto/ssh"
+)
+
+// MockFileSystem implements the FileSystem interface for testing
+type MockFileSystem struct {
+	Files          map[string][]byte
+	CreatedDirs    map[string]bool
+	OpenedFiles    map[string]*MockFile
+	StatCalledWith []string
+	FailOn         map[string]error // Map of function name to error to simulate failures
+}
+
+func NewMockFileSystem() *MockFileSystem {
+	return &MockFileSystem{
+		Files:       make(map[string][]byte),
+		CreatedDirs: make(map[string]bool),
+		OpenedFiles: make(map[string]*MockFile),
+		FailOn:      make(map[string]error),
+	}
+}
+
+func (m *MockFileSystem) Stat(name string) (fs.FileInfo, error) {
+	m.StatCalledWith = append(m.StatCalledWith, name)
+	if err, ok := m.FailOn["Stat"]; ok {
+		return nil, err
+	}
+
+	_, exists := m.Files[name]
+	if exists {
+		return nil, nil // File exists
+	}
+	_, exists = m.CreatedDirs[name]
+	if exists {
+		return nil, nil // Directory exists
+	}
+	return nil, os.ErrNotExist
+}
+
+func (m *MockFileSystem) Mkdir(name string, perm fs.FileMode) error {
+	if err, ok := m.FailOn["Mkdir"]; ok {
+		return err
+	}
+	m.CreatedDirs[name] = true
+	return nil
+}
+
+func (m *MockFileSystem) ReadFile(name string) ([]byte, error) {
+	if err, ok := m.FailOn["ReadFile"]; ok {
+		return nil, err
+	}
+
+	data, exists := m.Files[name]
+	if !exists {
+		return nil, fmt.Errorf("file not found: %s", name)
+	}
+	return data, nil
+}
+
+func (m *MockFileSystem) WriteFile(name string, data []byte, perm fs.FileMode) error {
+	if err, ok := m.FailOn["WriteFile"]; ok {
+		return err
+	}
+	m.Files[name] = data
+	return nil
+}
+
+// MockFile implements a simple in-memory file for testing
+type MockFile struct {
+	name     string
+	buffer   *bytes.Buffer
+	fs       *MockFileSystem
+	position int64
+}
+
+// MockFileContents represents in-memory file contents for testing
+type MockFileContents struct {
+	name     string
+	contents string
+}
+
+func (m *MockFileSystem) OpenFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
+	if err, ok := m.FailOn["OpenFile"]; ok {
+		return nil, err
+	}
+
+	// Initialize the file content if it doesn't exist and we're not in read-only mode
+	if _, exists := m.Files[name]; !exists && (flag&os.O_CREATE != 0) {
+		m.Files[name] = []byte{}
+	}
+
+	data, exists := m.Files[name]
+	if !exists {
+		return nil, fmt.Errorf("file not found: %s", name)
+	}
+
+	// For OpenFile, we'll just use WriteFile to simulate file operations
+	// The actual file handle isn't used for much in the sshtheater code
+	// but we still need to return a valid file handle
+	tmpFile, err := os.CreateTemp("", "mockfile-*")
+	if err != nil {
+		return nil, err
+	}
+	if _, err := tmpFile.Write(data); err != nil {
+		tmpFile.Close()
+		return nil, err
+	}
+	if _, err := tmpFile.Seek(0, 0); err != nil {
+		tmpFile.Close()
+		return nil, err
+	}
+
+	return tmpFile, nil
+}
+
+// MockKeyGenerator implements KeyGenerator interface for testing
+type MockKeyGenerator struct {
+	privateKey *rsa.PrivateKey
+	publicKey  ssh.PublicKey
+	FailOn     map[string]error
+}
+
+func NewMockKeyGenerator(privateKey *rsa.PrivateKey, publicKey ssh.PublicKey) *MockKeyGenerator {
+	return &MockKeyGenerator{
+		privateKey: privateKey,
+		publicKey:  publicKey,
+		FailOn:     make(map[string]error),
+	}
+}
+
+func (m *MockKeyGenerator) GeneratePrivateKey(bitSize int) (*rsa.PrivateKey, error) {
+	if err, ok := m.FailOn["GeneratePrivateKey"]; ok {
+		return nil, err
+	}
+	return m.privateKey, nil
+}
+
+func (m *MockKeyGenerator) GeneratePublicKey(privateKey *rsa.PublicKey) (ssh.PublicKey, error) {
+	if err, ok := m.FailOn["GeneratePublicKey"]; ok {
+		return nil, err
+	}
+	return m.publicKey, nil
+}
+
+// setupMocks sets up common mocks for testing
+func setupMocks(t *testing.T) (*MockFileSystem, *MockKeyGenerator, *rsa.PrivateKey) {
+	// Generate a real private key using real random
+	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
+	if err != nil {
+		t.Fatalf("Failed to generate test private key: %v", err)
+	}
+
+	// Generate a test public key
+	publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey)
+	if err != nil {
+		t.Fatalf("Failed to generate test public key: %v", err)
+	}
+
+	// Create mocks
+	mockFS := NewMockFileSystem()
+	mockKG := NewMockKeyGenerator(privateKey, publicKey)
+
+	return mockFS, mockKG, privateKey
+}
+
+// Helper function to setup a basic SSHTheater for testing
+func setupTestSSHTheater(t *testing.T) (*SSHTheater, *MockFileSystem, *MockKeyGenerator) {
+	mockFS, mockKG, _ := setupMocks(t)
+
+	// Setup home dir in mock filesystem
+	homePath := "/home/testuser"
+	sketchDir := filepath.Join(homePath, ".sketch")
+	mockFS.CreatedDirs[sketchDir] = true
+
+	// Set HOME environment variable for the test
+	oldHome := os.Getenv("HOME")
+	os.Setenv("HOME", homePath)
+	t.Cleanup(func() { os.Setenv("HOME", oldHome) })
+
+	// Create SSH Theater with mocks
+	ssh, err := newSSHTheatherWithDeps("test-container", "localhost", "2222", mockFS, mockKG)
+	if err != nil {
+		t.Fatalf("Failed to create SSHTheater: %v", err)
+	}
+
+	return ssh, mockFS, mockKG
+}
+
+func TestNewSSHTheatherCreatesRequiredDirectories(t *testing.T) {
+	mockFS, mockKG, _ := setupMocks(t)
+
+	// Set HOME environment variable for the test
+	oldHome := os.Getenv("HOME")
+	os.Setenv("HOME", "/home/testuser")
+	defer func() { os.Setenv("HOME", oldHome) }()
+
+	// Create theater
+	_, err := newSSHTheatherWithDeps("test-container", "localhost", "2222", mockFS, mockKG)
+	if err != nil {
+		t.Fatalf("Failed to create SSHTheater: %v", err)
+	}
+
+	// Check if the .sketch directory was created
+	expectedDir := "/home/testuser/.sketch"
+	if !mockFS.CreatedDirs[expectedDir] {
+		t.Errorf("Expected directory %s to be created", expectedDir)
+	}
+}
+
+func TestCreateKeyPairIfMissing(t *testing.T) {
+	ssh, mockFS, _ := setupTestSSHTheater(t)
+
+	// Test key pair creation
+	keyPath := "/home/testuser/.sketch/test_key"
+	_, err := ssh.createKeyPairIfMissing(keyPath)
+	if err != nil {
+		t.Fatalf("Failed to create key pair: %v", err)
+	}
+
+	// Verify private key file was created
+	if _, exists := mockFS.Files[keyPath]; !exists {
+		t.Errorf("Private key file not created at %s", keyPath)
+	}
+
+	// Verify public key file was created
+	pubKeyPath := keyPath + ".pub"
+	if _, exists := mockFS.Files[pubKeyPath]; !exists {
+		t.Errorf("Public key file not created at %s", pubKeyPath)
+	}
+
+	// Verify public key content format
+	pubKeyContent, _ := mockFS.ReadFile(pubKeyPath)
+	if !bytes.HasPrefix(pubKeyContent, []byte("ssh-rsa ")) {
+		t.Errorf("Public key does not have expected format, got: %s", pubKeyContent)
+	}
+}
+
+// TestAddContainerToSSHConfig tests that the container gets added to the SSH config
+// This test uses a direct approach since the OpenFile mocking is complex
+func TestAddContainerToSSHConfig(t *testing.T) {
+	// Create a temporary directory for test files
+	tempDir, err := os.MkdirTemp("", "sshtheater-test-*")
+	if err != nil {
+		t.Fatalf("Failed to create temp dir: %v", err)
+	}
+	defer os.RemoveAll(tempDir)
+
+	// Create real files in temp directory
+	configPath := filepath.Join(tempDir, "ssh_config")
+	initialConfig := `# SSH Config
+Host existing-host
+  HostName example.com
+  User testuser
+`
+	if err := os.WriteFile(configPath, []byte(initialConfig), 0644); err != nil {
+		t.Fatalf("Failed to write initial config: %v", err)
+	}
+
+	// Create a theater with the real filesystem but custom paths
+	ssh := &SSHTheater{
+		cntrName:         "test-container",
+		sshHost:          "localhost",
+		sshPort:          "2222",
+		sshConfigPath:    configPath,
+		userIdentityPath: filepath.Join(tempDir, "user_identity"),
+		fs:               &RealFileSystem{},
+		kg:               &RealKeyGenerator{},
+	}
+
+	// Add container to SSH config
+	err = ssh.addContainerToSSHConfig()
+	if err != nil {
+		t.Fatalf("Failed to add container to SSH config: %v", err)
+	}
+
+	// Read the updated file
+	configData, err := os.ReadFile(configPath)
+	if err != nil {
+		t.Fatalf("Failed to read updated config: %v", err)
+	}
+	configStr := string(configData)
+
+	// Check for expected values
+	if !strings.Contains(configStr, "Host test-container") {
+		t.Errorf("Container host entry not found in config")
+	}
+
+	if !strings.Contains(configStr, "HostName localhost") {
+		t.Errorf("HostName not correctly added to SSH config")
+	}
+
+	if !strings.Contains(configStr, "Port 2222") {
+		t.Errorf("Port not correctly added to SSH config")
+	}
+
+	if !strings.Contains(configStr, "User root") {
+		t.Errorf("User not correctly set to root in SSH config")
+	}
+
+	// Check if identity file path is correct
+	identityLine := "IdentityFile " + ssh.userIdentityPath
+	if !strings.Contains(configStr, identityLine) {
+		t.Errorf("Identity file path not correctly added to SSH config")
+	}
+}
+
+func TestAddContainerToKnownHosts(t *testing.T) {
+	// Skip this test as it requires more complex setup
+	// The TestSSHTheaterCleanup test covers the addContainerToKnownHosts
+	// functionality in a more integrated way
+	t.Skip("This test requires more complex setup, integrated test coverage exists in TestSSHTheaterCleanup")
+}
+
+func TestRemoveContainerFromSSHConfig(t *testing.T) {
+	// Create a temporary directory for test files
+	tempDir, err := os.MkdirTemp("", "sshtheater-test-*")
+	if err != nil {
+		t.Fatalf("Failed to create temp dir: %v", err)
+	}
+	defer os.RemoveAll(tempDir)
+
+	// Create paths for test files
+	sshConfigPath := filepath.Join(tempDir, "ssh_config")
+	userIdentityPath := filepath.Join(tempDir, "user_identity")
+	knownHostsPath := filepath.Join(tempDir, "known_hosts")
+
+	// Create initial SSH config with container entry
+	cntrName := "test-container"
+	sshHost := "localhost"
+	sshPort := "2222"
+
+	initialConfig := fmt.Sprintf(
+		`Host existing-host
+  HostName example.com
+  User testuser
+
+Host %s
+  HostName %s
+  User root
+  Port %s
+  IdentityFile %s
+  UserKnownHostsFile %s
+`,
+		cntrName, sshHost, sshPort, userIdentityPath, knownHostsPath,
+	)
+
+	if err := os.WriteFile(sshConfigPath, []byte(initialConfig), 0644); err != nil {
+		t.Fatalf("Failed to write initial SSH config: %v", err)
+	}
+
+	// Create a theater with the real filesystem but custom paths
+	ssh := &SSHTheater{
+		cntrName:         cntrName,
+		sshHost:          sshHost,
+		sshPort:          sshPort,
+		sshConfigPath:    sshConfigPath,
+		userIdentityPath: userIdentityPath,
+		knownHostsPath:   knownHostsPath,
+		fs:               &RealFileSystem{},
+	}
+
+	// Remove container from SSH config
+	err = ssh.removeContainerFromSSHConfig()
+	if err != nil {
+		t.Fatalf("Failed to remove container from SSH config: %v", err)
+	}
+
+	// Read the updated file
+	configData, err := os.ReadFile(sshConfigPath)
+	if err != nil {
+		t.Fatalf("Failed to read updated config: %v", err)
+	}
+	configStr := string(configData)
+
+	// Check if the container host entry was removed
+	if strings.Contains(configStr, "Host "+cntrName) {
+		t.Errorf("Container host not removed from SSH config")
+	}
+
+	// Check if existing host remains
+	if !strings.Contains(configStr, "Host existing-host") {
+		t.Errorf("Existing host entry affected by container removal")
+	}
+}
+
+func TestRemoveContainerFromKnownHosts(t *testing.T) {
+	ssh, mockFS, _ := setupTestSSHTheater(t)
+
+	// Setup server public key
+	privateKey, _ := ssh.kg.GeneratePrivateKey(2048)
+	publicKey, _ := ssh.kg.GeneratePublicKey(&privateKey.PublicKey)
+	ssh.serverPublicKey = publicKey
+
+	// Create host line to be removed
+	hostLine := "[localhost]:2222 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ..."
+	otherLine := "otherhost ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ..."
+
+	// Set initial content with the line to be removed
+	initialContent := otherLine + "\n" + hostLine
+	mockFS.Files[ssh.knownHostsPath] = []byte(initialContent)
+
+	// Add the host to test remove function
+	err := ssh.addContainerToKnownHosts()
+	if err != nil {
+		t.Fatalf("Failed to add container to known_hosts for removal test: %v", err)
+	}
+
+	// Now remove it
+	err = ssh.removeContainerFromKnownHosts()
+	if err != nil {
+		t.Fatalf("Failed to remove container from known_hosts: %v", err)
+	}
+
+	// Verify content
+	updatedContent, _ := mockFS.ReadFile(ssh.knownHostsPath)
+	content := string(updatedContent)
+
+	hostPattern := ssh.sshHost + ":" + ssh.sshPort
+	if strings.Contains(content, hostPattern) {
+		t.Errorf("Container entry not removed from known_hosts")
+	}
+
+	// Verify other content remains
+	if !strings.Contains(content, otherLine) {
+		t.Errorf("Other known_hosts entries improperly removed")
+	}
+}
+
+func TestSSHTheaterCleanup(t *testing.T) {
+	// Create a temporary directory for test files
+	tempDir, err := os.MkdirTemp("", "sshtheater-test-*")
+	if err != nil {
+		t.Fatalf("Failed to create temp dir: %v", err)
+	}
+	defer os.RemoveAll(tempDir)
+
+	// Create paths for test files
+	sshConfigPath := filepath.Join(tempDir, "ssh_config")
+	userIdentityPath := filepath.Join(tempDir, "user_identity")
+	knownHostsPath := filepath.Join(tempDir, "known_hosts")
+	serverIdentityPath := filepath.Join(tempDir, "server_identity")
+
+	// Create private key for server key
+	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
+	if err != nil {
+		t.Fatalf("Failed to generate private key: %v", err)
+	}
+	publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey)
+	if err != nil {
+		t.Fatalf("Failed to generate public key: %v", err)
+	}
+
+	// Initialize files
+	os.WriteFile(sshConfigPath, []byte("initial ssh_config content"), 0644)
+	os.WriteFile(knownHostsPath, []byte("initial known_hosts content"), 0644)
+
+	// Create a theater with the real filesystem but custom paths
+	cntrName := "test-container"
+	sshHost := "localhost"
+	sshPort := "2222"
+
+	ssh := &SSHTheater{
+		cntrName:           cntrName,
+		sshHost:            sshHost,
+		sshPort:            sshPort,
+		sshConfigPath:      sshConfigPath,
+		userIdentityPath:   userIdentityPath,
+		knownHostsPath:     knownHostsPath,
+		serverIdentityPath: serverIdentityPath,
+		serverPublicKey:    publicKey,
+		fs:                 &RealFileSystem{},
+		kg:                 &RealKeyGenerator{},
+	}
+
+	// Add container to configs
+	err = ssh.addContainerToSSHConfig()
+	if err != nil {
+		t.Fatalf("Failed to set up SSH config for cleanup test: %v", err)
+	}
+
+	err = ssh.addContainerToKnownHosts()
+	if err != nil {
+		t.Fatalf("Failed to set up known_hosts for cleanup test: %v", err)
+	}
+
+	// Execute cleanup
+	err = ssh.Cleanup()
+	if err != nil {
+		t.Fatalf("Cleanup failed: %v", err)
+	}
+
+	// Read updated files
+	configData, err := os.ReadFile(sshConfigPath)
+	if err != nil {
+		t.Fatalf("Failed to read updated SSH config: %v", err)
+	}
+	configStr := string(configData)
+
+	// Check container was removed from SSH config
+	hostEntry := "Host " + ssh.cntrName
+	if strings.Contains(configStr, hostEntry) {
+		t.Errorf("Container not removed from SSH config during cleanup")
+	}
+
+	// Verify known hosts was updated
+	knownHostsContent, err := os.ReadFile(knownHostsPath)
+	if err != nil {
+		t.Fatalf("Failed to read updated known_hosts: %v", err)
+	}
+
+	expectedHostPattern := ssh.sshHost + ":" + ssh.sshPort
+	if strings.Contains(string(knownHostsContent), expectedHostPattern) {
+		t.Errorf("Container not removed from known_hosts during cleanup")
+	}
+}
+
+func TestCheckForInclude(t *testing.T) {
+	mockFS := NewMockFileSystem()
+
+	// Set HOME environment variable for the test
+	oldHome := os.Getenv("HOME")
+	os.Setenv("HOME", "/home/testuser")
+	defer func() { os.Setenv("HOME", oldHome) }()
+
+	// Create a mock ssh config with the expected include
+	includeLine := "Include /home/testuser/.sketch/ssh_config"
+	initialConfig := fmt.Sprintf("%s\nHost example\n  HostName example.com\n", includeLine)
+
+	// Add the config to the mock filesystem
+	sshConfigPath := "/home/testuser/.ssh/config"
+	mockFS.Files[sshConfigPath] = []byte(initialConfig)
+
+	// Test the function with our mock
+	err := CheckForIncludeWithFS(mockFS)
+	if err != nil {
+		t.Fatalf("CheckForInclude failed with proper include: %v", err)
+	}
+
+	// Now test with config missing the include
+	mockFS.Files[sshConfigPath] = []byte("Host example\n  HostName example.com\n")
+
+	err = CheckForIncludeWithFS(mockFS)
+	if err == nil {
+		t.Fatalf("CheckForInclude should have returned an error for missing include")
+	}
+}
+
+func TestSSHTheaterWithErrors(t *testing.T) {
+	// Test directory creation failure
+	mockFS := NewMockFileSystem()
+	mockFS.FailOn["Mkdir"] = fmt.Errorf("mock mkdir error")
+	mockKG := NewMockKeyGenerator(nil, nil)
+
+	// Set HOME environment variable for the test
+	oldHome := os.Getenv("HOME")
+	os.Setenv("HOME", "/home/testuser")
+	defer func() { os.Setenv("HOME", oldHome) }()
+
+	// Try to create theater with failing FS
+	_, err := newSSHTheatherWithDeps("test-container", "localhost", "2222", mockFS, mockKG)
+	if err == nil || !strings.Contains(err.Error(), "mock mkdir error") {
+		t.Errorf("Should have failed with mkdir error, got: %v", err)
+	}
+
+	// Test key generation failure
+	mockFS = NewMockFileSystem()
+	mockKG = NewMockKeyGenerator(nil, nil)
+	mockKG.FailOn["GeneratePrivateKey"] = fmt.Errorf("mock key generation error")
+
+	_, err = newSSHTheatherWithDeps("test-container", "localhost", "2222", mockFS, mockKG)
+	if err == nil || !strings.Contains(err.Error(), "key generation error") {
+		t.Errorf("Should have failed with key generation error, got: %v", err)
+	}
+}
+
+func TestRealSSHTheatherInit(t *testing.T) {
+	// This is a basic smoke test for the real NewSSHTheather method
+	// We'll mock the os.Getenv("HOME") but use real dependencies otherwise
+
+	// Create a temp dir to use as HOME
+	tempDir, err := os.MkdirTemp("", "sshtheater-test-home-*")
+	if err != nil {
+		t.Fatalf("Failed to create temp dir: %v", err)
+	}
+	defer os.RemoveAll(tempDir)
+
+	// Set HOME environment for the test
+	oldHome := os.Getenv("HOME")
+	os.Setenv("HOME", tempDir)
+	defer os.Setenv("HOME", oldHome)
+
+	// Create the theater
+	theater, err := NewSSHTheather("test-container", "localhost", "2222")
+	if err != nil {
+		t.Fatalf("Failed to create real SSHTheather: %v", err)
+	}
+
+	// Just some basic checks
+	if theater == nil {
+		t.Fatal("Theater is nil")
+	}
+
+	// Check if the sketch dir was created
+	sketchDir := filepath.Join(tempDir, ".sketch")
+	if _, err := os.Stat(sketchDir); os.IsNotExist(err) {
+		t.Errorf(".sketch directory not created")
+	}
+
+	// Check if key files were created
+	if _, err := os.Stat(theater.serverIdentityPath); os.IsNotExist(err) {
+		t.Errorf("Server identity file not created")
+	}
+
+	if _, err := os.Stat(theater.userIdentityPath); os.IsNotExist(err) {
+		t.Errorf("User identity file not created")
+	}
+
+	// Check if the config files were created
+	if _, err := os.Stat(theater.sshConfigPath); os.IsNotExist(err) {
+		t.Errorf("SSH config file not created")
+	}
+
+	if _, err := os.Stat(theater.knownHostsPath); os.IsNotExist(err) {
+		t.Errorf("Known hosts file not created")
+	}
+
+	// Clean up
+	err = theater.Cleanup()
+	if err != nil {
+		t.Fatalf("Failed to clean up theater: %v", err)
+	}
+}
