package models import ( "bufio" "encoding/json" "errors" "os" "path/filepath" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestParseSetupError(t *testing.T) { tests := []struct { name string err error expected string }{ { name: "valid nixery error", err: errors.New(`Error response from daemon: unknown: {"errors":[{"code":"MANIFEST_UNKNOWN","message":"Could not find Nix packages: [gopher123]"}]}`), expected: "Could not find Nix packages: [gopher123]", }, { name: "multiple errors returns first", err: errors.New(`Error response from daemon: unknown: {"errors":[{"code":"A","message":"first error"},{"code":"B","message":"second error"}]}`), expected: "first error", }, { name: "no unknown marker fallback", err: errors.New("some other docker error"), expected: "some other docker error", }, { name: "malformed JSON fallback", err: errors.New(`Error response from daemon: unknown: {invalid json}`), expected: `Error response from daemon: unknown: {invalid json}`, }, { name: "empty errors array fallback", err: errors.New(`Error response from daemon: unknown: {"errors":[]}`), expected: `Error response from daemon: unknown: {"errors":[]}`, }, { name: "empty message field fallback", err: errors.New(`Error response from daemon: unknown: {"errors":[{"code":"X","message":""}]}`), expected: `Error response from daemon: unknown: {"errors":[{"code":"X","message":""}]}`, }, { name: "nil error", err: nil, expected: "", }, { name: "real world nixery error", err: errors.New(`Error response from daemon: unknown: {"errors":[{"code":"MANIFEST_UNKNOWN","message":"Could not find Nix packages: [nonexistent-package-xyz]"}]}`), expected: "Could not find Nix packages: [nonexistent-package-xyz]", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := ParseSetupError(tt.err) assert.Equal(t, tt.expected, result) }) } } func TestWriteSetupError(t *testing.T) { // Create temp directory tempDir := t.TempDir() wid := WorkflowId{ PipelineId: PipelineId{ Knot: "test.example.com", Rkey: "abc123", }, Name: "test-workflow", } // Create logger logger, err := NewWorkflowLogger(tempDir, wid) require.NoError(t, err) defer logger.Close() // Write setup error testMessage := "Could not find Nix packages: [gopher123]" err = logger.WriteSetupError(testMessage) require.NoError(t, err) // Close logger to flush err = logger.Close() require.NoError(t, err) // Read the log file logPath := filepath.Join(tempDir, wid.String()+".log") file, err := os.Open(logPath) require.NoError(t, err) defer file.Close() scanner := bufio.NewScanner(file) // Line 1: Control message (step start) require.True(t, scanner.Scan(), "expected control start line") var controlStart LogLine require.NoError(t, json.Unmarshal(scanner.Bytes(), &controlStart)) assert.Equal(t, LogKindControl, controlStart.Kind) assert.Equal(t, "Setup", controlStart.Content) assert.Equal(t, 0, controlStart.StepId) assert.Equal(t, StepKindSystem, controlStart.StepKind) assert.Equal(t, StepStatusStart, controlStart.StepStatus) // Line 2: Data message (error content) require.True(t, scanner.Scan(), "expected data line") var dataLine LogLine require.NoError(t, json.Unmarshal(scanner.Bytes(), &dataLine)) assert.Equal(t, LogKindData, dataLine.Kind) assert.Equal(t, testMessage, dataLine.Content) assert.Equal(t, 0, dataLine.StepId) assert.Equal(t, "stderr", dataLine.Stream) // Line 3: Control message (step end) require.True(t, scanner.Scan(), "expected control end line") var controlEnd LogLine require.NoError(t, json.Unmarshal(scanner.Bytes(), &controlEnd)) assert.Equal(t, LogKindControl, controlEnd.Kind) assert.Equal(t, StepStatusEnd, controlEnd.StepStatus) }