|
5 | 5 | "os" |
6 | 6 | "path/filepath" |
7 | 7 | "testing" |
| 8 | + "time" |
8 | 9 |
|
9 | 10 | "github.com/Norgate-AV/spc/internal/config" |
10 | 11 | "github.com/stretchr/testify/assert" |
@@ -867,3 +868,99 @@ func TestCache_UshFiles_TargetSpecific(t *testing.T) { |
867 | 868 | } |
868 | 869 | } |
869 | 870 | } |
| 871 | + |
| 872 | +// TestCache_Restore_SkipsIdenticalFiles verifies that restoration only copies files |
| 873 | +// when necessary, skipping identical files to improve performance |
| 874 | +func TestCache_Restore_SkipsIdenticalFiles(t *testing.T) { |
| 875 | + cacheDir := t.TempDir() |
| 876 | + sourceDir := t.TempDir() |
| 877 | + sourceFile := filepath.Join(sourceDir, "test.usp") |
| 878 | + splsWorkDir := filepath.Join(sourceDir, "SPlsWork") |
| 879 | + |
| 880 | + // Create source file |
| 881 | + err := os.WriteFile(sourceFile, []byte("test source"), 0o644) |
| 882 | + require.NoError(t, err) |
| 883 | + |
| 884 | + // Create SPlsWork directory |
| 885 | + err = os.MkdirAll(splsWorkDir, 0o755) |
| 886 | + require.NoError(t, err) |
| 887 | + |
| 888 | + // Create output files |
| 889 | + outputs := []string{"test.dll", "test.cs"} |
| 890 | + for _, output := range outputs { |
| 891 | + path := filepath.Join(splsWorkDir, output) |
| 892 | + err := os.WriteFile(path, []byte(fmt.Sprintf("content of %s", output)), 0o644) |
| 893 | + require.NoError(t, err) |
| 894 | + } |
| 895 | + |
| 896 | + // Create .ush file |
| 897 | + ushFile := filepath.Join(sourceDir, "test.ush") |
| 898 | + err = os.WriteFile(ushFile, []byte("header content"), 0o644) |
| 899 | + require.NoError(t, err) |
| 900 | + |
| 901 | + // Create cache and store |
| 902 | + cache, err := New(cacheDir) |
| 903 | + require.NoError(t, err) |
| 904 | + defer cache.Close() |
| 905 | + |
| 906 | + cfg := &config.Config{Target: "3", UserFolders: []string{}} |
| 907 | + err = cache.Store(sourceFile, cfg, true) |
| 908 | + require.NoError(t, err) |
| 909 | + |
| 910 | + // Get entry |
| 911 | + entry, err := cache.Get(sourceFile, cfg) |
| 912 | + require.NoError(t, err) |
| 913 | + require.NotNil(t, entry) |
| 914 | + |
| 915 | + // First restoration (files don't exist) - should copy all files |
| 916 | + restoreDir1 := t.TempDir() |
| 917 | + err = cache.Restore(entry, restoreDir1) |
| 918 | + require.NoError(t, err) |
| 919 | + |
| 920 | + // Verify files were created |
| 921 | + for _, output := range outputs { |
| 922 | + assert.FileExists(t, filepath.Join(restoreDir1, "SPlsWork", output)) |
| 923 | + } |
| 924 | + assert.FileExists(t, filepath.Join(restoreDir1, "test.ush")) |
| 925 | + |
| 926 | + // Get timestamps of restored files |
| 927 | + dllPath := filepath.Join(restoreDir1, "SPlsWork", "test.dll") |
| 928 | + infoBeforeSecondRestore, err := os.Stat(dllPath) |
| 929 | + require.NoError(t, err) |
| 930 | + |
| 931 | + // Wait a moment to ensure timestamps would differ if file was rewritten |
| 932 | + time.Sleep(10 * time.Millisecond) |
| 933 | + |
| 934 | + // Second restoration (files already exist and are identical) - should skip copying |
| 935 | + err = cache.Restore(entry, restoreDir1) |
| 936 | + require.NoError(t, err) |
| 937 | + |
| 938 | + // Verify file timestamp didn't change (file wasn't copied) |
| 939 | + infoAfterSecondRestore, err := os.Stat(dllPath) |
| 940 | + require.NoError(t, err) |
| 941 | + assert.Equal(t, infoBeforeSecondRestore.ModTime(), infoAfterSecondRestore.ModTime(), |
| 942 | + "File should not be copied when it's already identical") |
| 943 | + |
| 944 | + // Now modify a file to make it different |
| 945 | + err = os.WriteFile(dllPath, []byte("corrupted content"), 0o644) |
| 946 | + require.NoError(t, err) |
| 947 | + |
| 948 | + infoAfterModification, err := os.Stat(dllPath) |
| 949 | + require.NoError(t, err) |
| 950 | + |
| 951 | + // Third restoration (file exists but differs) - should copy the modified file |
| 952 | + time.Sleep(10 * time.Millisecond) |
| 953 | + err = cache.Restore(entry, restoreDir1) |
| 954 | + require.NoError(t, err) |
| 955 | + |
| 956 | + // Verify file was restored (timestamp changed and content correct) |
| 957 | + infoAfterThirdRestore, err := os.Stat(dllPath) |
| 958 | + require.NoError(t, err) |
| 959 | + assert.NotEqual(t, infoAfterModification.ModTime(), infoAfterThirdRestore.ModTime(), |
| 960 | + "File should be copied when it differs from cached version") |
| 961 | + |
| 962 | + // Verify content was correctly restored |
| 963 | + content, err := os.ReadFile(dllPath) |
| 964 | + require.NoError(t, err) |
| 965 | + assert.Equal(t, "content of test.dll", string(content), "Content should be restored correctly") |
| 966 | +} |
0 commit comments