Skip to content

Commit

Permalink
Run dir-cache invalidation in backend, not tests
Browse files Browse the repository at this point in the history
This way the NFS dir cache will be invalidated as soon as we know it's
necessary to do so, and we won't end up needing to add a cache
invalidation step to our tests.
  • Loading branch information
rmunn committed May 9, 2024
1 parent 3bbb7e0 commit 9691a40
Show file tree
Hide file tree
Showing 5 changed files with 10 additions and 17 deletions.
10 changes: 10 additions & 0 deletions backend/LexBoxApi/Services/HgService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ await Task.Run(() =>
{
InitRepoAt(new DirectoryInfo(PrefixRepoFilePath(code)));
});
await InvalidateDirCache(code);
}

private void InitRepoAt(DirectoryInfo repoDirectory)
Expand All @@ -82,6 +83,7 @@ private void InitRepoAt(DirectoryInfo repoDirectory)
public async Task DeleteRepo(string code)
{
await Task.Run(() => Directory.Delete(PrefixRepoFilePath(code), true));
await InvalidateDirCache(code);
}

public BackupExecutor? BackupRepo(string code)
Expand All @@ -104,6 +106,7 @@ public async Task ResetRepo(string code)
await SoftDeleteRepo(code, $"{FileUtils.ToTimestamp(DateTimeOffset.UtcNow)}__reset");
//we must init the repo as uploading a zip is optional
tmpRepo.MoveTo(PrefixRepoFilePath(code));
await InvalidateDirCache(code);
}

public async Task FinishReset(string code, Stream zipFile)
Expand Down Expand Up @@ -137,6 +140,7 @@ await Task.Run(() =>
// Now we're ready to move the new repo into place, replacing the old one
await DeleteRepo(code);
tempRepo.MoveTo(PrefixRepoFilePath(code));
await InvalidateDirCache(code);
}

/// <summary>
Expand Down Expand Up @@ -181,6 +185,7 @@ await Task.Run(() =>
PrefixRepoFilePath(code),
Path.Combine(deletedRepoPath, deletedRepoName));
});
await InvalidateDirCache(code);
}

private const UnixFileMode Permissions = UnixFileMode.GroupRead | UnixFileMode.GroupWrite |
Expand Down Expand Up @@ -262,6 +267,11 @@ public async Task<HttpContent> ExecuteHgRecover(string code, CancellationToken t
return response;
}

public async Task InvalidateDirCache(string code)
{
await ExecuteHgCommandServerCommand(code, "invalidatedircache", default);
}

public async Task<int?> GetLexEntryCount(string code, ProjectType projectType)
{
var command = projectType switch
Expand Down
6 changes: 0 additions & 6 deletions backend/Testing/ApiTests/ApiTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,4 @@ public async Task StartLexboxProjectReset(string projectCode)
var response = await HttpClient.PostAsync($"{BaseUrl}/api/project/resetProject/{projectCode}", null);
response.EnsureSuccessStatusCode();
}

public async Task InvalidateDirCache(string projectCode)
{
var response = await HttpClient.PostAsync($"{BaseUrl}/hg/command/{projectCode}/invalidatedircache", null);
response.EnsureSuccessStatusCode();
}
}
1 change: 0 additions & 1 deletion backend/Testing/Services/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ ... on DbError {
}
}
""");
await apiTester.InvalidateDirCache(config.Code); // Ensure newly-created project is available right away
return new LexboxProject(apiTester, config.Id);
}

Expand Down
8 changes: 0 additions & 8 deletions backend/Testing/SyncReverseProxy/SendReceiveServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,6 @@ public async Task ModifyProjectData(HgProtocol protocol)
var sendReceiveParams = new SendReceiveParams(protocol, projectConfig);
_sendReceiveService.SendReceiveProject(sendReceiveParams, AdminAuth);

await _adminApiTester.InvalidateDirCache(projectConfig.Code);

// Verify pushed and store last commit
var lastCommitDate = await _adminApiTester.GetProjectLastCommit(projectConfig.Code);
lastCommitDate.ShouldNotBeNullOrEmpty();
Expand All @@ -99,8 +97,6 @@ public async Task ModifyProjectData(HgProtocol protocol)
// Push changes
_sendReceiveService.SendReceiveProject(sendReceiveParams, AdminAuth, "Modify project data automated test");

await _adminApiTester.InvalidateDirCache(projectConfig.Code);

// Verify the push updated the last commit date
var lastCommitDateAfter = await _adminApiTester.GetProjectLastCommit(projectConfig.Code);
lastCommitDateAfter.ShouldBeGreaterThan(lastCommitDate);
Expand Down Expand Up @@ -140,8 +136,6 @@ public async Task SendReceiveAfterProjectReset(HgProtocol protocol)
await _adminApiTester.HttpClient.PostAsync($"{_adminApiTester.BaseUrl}/api/project/resetProject/{projectConfig.Code}", null);
await _adminApiTester.HttpClient.PostAsync($"{_adminApiTester.BaseUrl}/api/project/finishResetProject/{projectConfig.Code}", null);

await _adminApiTester.InvalidateDirCache(projectConfig.Code);

// Step 2: verify project is now empty, i.e. tip is "0000000..."
response = await _adminApiTester.HttpClient.GetAsync(tipUri.Uri);
jsonResult = await response.Content.ReadFromJsonAsync<JsonObject>();
Expand All @@ -165,8 +159,6 @@ public async Task SendReceiveAfterProjectReset(HgProtocol protocol)
var srResultStep3 = _sendReceiveService.SendReceiveProject(sendReceiveParams, AdminAuth);
_output.WriteLine(srResultStep3);

await _adminApiTester.InvalidateDirCache(projectConfig.Code);

// Step 4: verify project tip is same hash as original project tip
response = await _adminApiTester.HttpClient.GetAsync(tipUri.Uri);
jsonResult = await response.Content.ReadFromJsonAsync<JsonObject>();
Expand Down
2 changes: 0 additions & 2 deletions frontend/tests/resetProject.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ test('reset project and upload .zip file', async ({ page, tempProject, tempDir }
await resetProjectModel.assertGone();

// Step 4: confirm it's empty now
await page.request.get(`${testEnv.serverBaseUrl}/hg/command/${tempProject.code}/invalidatedircache`); // Force an NFS cache clear
const afterResetResponse = await page.request.get(`${testEnv.serverBaseUrl}/hg/${tempProject.code}/file/tip?style=json-lex`);
const afterResetJson = await afterResetResponse.json() as HgWebJson;
expect(afterResetJson.node).toEqual(allZeroHash);
Expand All @@ -78,7 +77,6 @@ test('reset project and upload .zip file', async ({ page, tempProject, tempDir }
await resetProjectModel.assertGone();

// Step 6: confirm tip hash and contents are same as before reset
await page.request.get(`${testEnv.serverBaseUrl}/hg/command/${tempProject.code}/invalidatedircache`); // Force an NFS cache clear
const afterUploadResponse = await page.request.get(`${testEnv.serverBaseUrl}/hg/${tempProject.code}/file/tip?style=json-lex`);
const afterResetJSon = await afterUploadResponse.json() as HgWebJson;
expect(afterResetJSon).toEqual(beforeResetJson); // NOT .toBe(), which would check that they're the same object.
Expand Down

0 comments on commit 9691a40

Please sign in to comment.