diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4166bab3..71a1263e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -103,8 +103,8 @@ jobs: - name: Test Windows auth and DPAPI packages run: go test -v -count=1 -timeout=10m ./internal/keychain ./internal/auth - - name: Test Windows auth migration and export diagnostics - run: go test -v -count=1 -timeout=5m ./internal/app -run '^TestAuth(MigrateKeychain|StatusDiagnosticReportsCiphertextKeyMismatch|ExportRejectsWindowsDPAPIBackend)' + - name: Test Windows auth migration and portable auth diagnostics + run: go test -v -count=1 -timeout=5m ./internal/app -run '^Test(CrossPlatformCoverage)?Auth(MigrateKeychain|StatusDiagnosticReportsCiphertextKeyMismatch|ExportRejectsWindowsDPAPIBackend|ImportRejectsWindowsDPAPIBackend)' coverage-darwin: name: Coverage (macOS) diff --git a/internal/app/auth_command_test.go b/internal/app/auth_command_test.go index 02d6b607..fb8b89b8 100644 --- a/internal/app/auth_command_test.go +++ b/internal/app/auth_command_test.go @@ -102,7 +102,7 @@ func TestAuthExportImportBase64RoundTrip(t *testing.T) { } } -func TestAuthExportUnsupportedBackendIsValidationError(t *testing.T) { +func TestCrossPlatformCoverageAuthExportUnsupportedBackendIsValidationError(t *testing.T) { exportCmd := newAuthExportCommandWithSupport(func() error { return errors.New("portable auth export is unavailable for the test backend") }) @@ -123,7 +123,7 @@ func TestAuthExportUnsupportedBackendIsValidationError(t *testing.T) { } } -func TestAuthExportRejectsWindowsDPAPIBackend(t *testing.T) { +func TestCrossPlatformCoverageAuthExportRejectsWindowsDPAPIBackend(t *testing.T) { if runtime.GOOS != "windows" { t.Skip("Windows DPAPI contract requires a native Windows runner") } @@ -149,7 +149,7 @@ func TestAuthExportRejectsWindowsDPAPIBackend(t *testing.T) { } } -func TestAuthImportUnsupportedBackendIsValidationErrorBeforeReadingInput(t *testing.T) { +func TestCrossPlatformCoverageAuthImportUnsupportedBackendIsValidationErrorBeforeReadingInput(t *testing.T) { root := t.TempDir() configDir := filepath.Join(root, ".dws") keychainDir := filepath.Join(root, "keychain") @@ -181,7 +181,7 @@ func TestAuthImportUnsupportedBackendIsValidationErrorBeforeReadingInput(t *test } } -func TestAuthImportRejectsWindowsDPAPIBackend(t *testing.T) { +func TestCrossPlatformCoverageAuthImportRejectsWindowsDPAPIBackend(t *testing.T) { if runtime.GOOS != "windows" { t.Skip("Windows DPAPI contract requires a native Windows runner") } @@ -222,7 +222,7 @@ func TestAuthImportRejectsWindowsDPAPIBackend(t *testing.T) { } } -func TestAuthImportRequiresForceWhenPopulated(t *testing.T) { +func TestCrossPlatformCoverageAuthImportRequiresForceWhenPopulated(t *testing.T) { t.Setenv(keychain.DisableKeychainEnv, "1") root := t.TempDir() t.Cleanup(CloseFileLogger) diff --git a/internal/app/test_home_test.go b/internal/app/test_home_test.go index 50d6fb8a..51a534e7 100644 --- a/internal/app/test_home_test.go +++ b/internal/app/test_home_test.go @@ -29,7 +29,7 @@ func setTestHome(t *testing.T, home string) { } } -func TestConfigureLogLevelTerminatesReplacedFileLoggers(t *testing.T) { +func TestCrossPlatformCoverageConfigureLogLevelTerminatesReplacedFileLoggers(t *testing.T) { firstConfig := t.TempDir() secondConfig := t.TempDir() t.Cleanup(CloseFileLogger) diff --git a/internal/auth/portable_store_test.go b/internal/auth/portable_store_test.go index e2116ee0..9fc98ec5 100644 --- a/internal/auth/portable_store_test.go +++ b/internal/auth/portable_store_test.go @@ -28,7 +28,7 @@ import ( "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/keychain" ) -func TestPortableExportSupported(t *testing.T) { +func TestCrossPlatformCoveragePortableExportSupported(t *testing.T) { switch runtime.GOOS { case "windows": if PortableExportSupported() { @@ -60,7 +60,7 @@ func TestPortableExportSupported(t *testing.T) { } } -func TestPortableExportSupportError(t *testing.T) { +func TestCrossPlatformCoveragePortableExportSupportError(t *testing.T) { tests := []struct { name string goos string @@ -89,7 +89,7 @@ func TestPortableExportSupportError(t *testing.T) { } } -func TestPortableImportSupportError(t *testing.T) { +func TestCrossPlatformCoveragePortableImportSupportError(t *testing.T) { tests := []struct { name string goos string @@ -116,7 +116,7 @@ func TestPortableImportSupportError(t *testing.T) { } } -func TestImportPortableAuthBundleRejectsWindowsDPAPIWithoutMutation(t *testing.T) { +func TestCrossPlatformCoverageImportPortableAuthBundleRejectsWindowsDPAPIWithoutMutation(t *testing.T) { if runtime.GOOS != "windows" { t.Skip("Windows DPAPI contract requires a native Windows runner") } diff --git a/internal/logging/logger_test.go b/internal/logging/logger_test.go index 326061e4..f5bf7dfe 100644 --- a/internal/logging/logger_test.go +++ b/internal/logging/logger_test.go @@ -123,7 +123,7 @@ func TestCloseOnNilLogger(t *testing.T) { } } -func TestFileLoggerCloseIsTerminal(t *testing.T) { +func TestCrossPlatformCoverageFileLoggerCloseIsTerminal(t *testing.T) { t.Parallel() dir := t.TempDir() @@ -136,6 +136,15 @@ func TestFileLoggerCloseIsTerminal(t *testing.T) { if err := os.Remove(logPath); err != nil { t.Fatalf("remove closed log file: %v", err) } + if err := fl.writer.open(); !errors.Is(err, os.ErrClosed) { + t.Fatalf("open after close = %v, want os.ErrClosed", err) + } + fl.writer.mu.Lock() + err := fl.writer.reopenLocked() + fl.writer.mu.Unlock() + if !errors.Is(err, os.ErrClosed) { + t.Fatalf("reopen after close = %v, want os.ErrClosed", err) + } n, err := fl.Writer().Write([]byte("late write")) if n != 0 || !errors.Is(err, os.ErrClosed) {