Skip to content

Commit

Permalink
Create new invalidatedircache command in runner
Browse files Browse the repository at this point in the history
This command will do nothing except run an `ls` on the requested project
code. The intent is to run this command during testing after a project
reset, in order to immediately invalidate the NFS dir cache on hgweb and
make the new state of the project available. It will likely not be needed
in production, because the only time the NFS cache has been relevant in
production (or staging) is when lexentrycount is run after a project
reset, and the `ls` is already baked into the lexentrycount command. But
in testing, it will sometimes be necessary to reset the NFS directory
cache in order to make the result of a project reset available right
away, which will allow the tests to stop being flaky.
  • Loading branch information
rmunn committed May 8, 2024
1 parent 5cc036e commit cfc5a43
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 13 deletions.
6 changes: 6 additions & 0 deletions backend/Testing/ApiTests/ApiTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,10 @@ 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();
}
}
6 changes: 3 additions & 3 deletions backend/Testing/SyncReverseProxy/SendReceiveServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public async Task SendReceiveAfterProjectReset(HgProtocol protocol)
var projectConfig = _srFixture.InitLocalFlexProjectWithRepo(protocol, "SR_AfterReset");
await using var project = await RegisterProjectInLexBox(projectConfig, _adminApiTester);

await WaitForHgRefreshIntervalAsync();
await _adminApiTester.InvalidateDirCache(projectConfig.Code);

var sendReceiveParams = new SendReceiveParams(protocol, projectConfig);
var srResult = _sendReceiveService.SendReceiveProject(sendReceiveParams, AdminAuth);
Expand All @@ -144,7 +144,7 @@ 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 WaitForHgRefreshIntervalAsync(); // TODO 765: Remove this
await _adminApiTester.InvalidateDirCache(projectConfig.Code);

// Step 2: verify project is now empty, i.e. tip is "0000000..."
response = await _adminApiTester.HttpClient.GetAsync(tipUri.Uri);
Expand All @@ -169,7 +169,7 @@ public async Task SendReceiveAfterProjectReset(HgProtocol protocol)
var srResultStep3 = _sendReceiveService.SendReceiveProject(sendReceiveParams, AdminAuth);
_output.WriteLine(srResultStep3);

await WaitForHgRefreshIntervalAsync(); // TODO 765: Remove this
await _adminApiTester.InvalidateDirCache(projectConfig.Code);

// Step 4: verify project tip is same hash as original project tip
response = await _adminApiTester.HttpClient.GetAsync(tipUri.Uri);
Expand Down
14 changes: 5 additions & 9 deletions frontend/tests/resetProject.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ 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}/tip`); // Force an NFS cache clear, ignore result
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,12 +78,8 @@ 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
// It can take a while for the server to pick up the new repo
await expect(async () => {
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.
}).toPass({
intervals: [1_000, 3_000, 5_000],
});
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.
});
6 changes: 5 additions & 1 deletion hgweb/command-runner.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash

# Define the list of allowed commands
allowed_commands=("verify" "tip" "wesaylexentrycount" "lexentrycount" "recover")
allowed_commands=("verify" "tip" "wesaylexentrycount" "lexentrycount" "recover", "invalidatedircache")

# Get the project code and command name from the URL
IFS='/' read -ra PATH_SEGMENTS <<< "$PATH_INFO"
Expand Down Expand Up @@ -63,6 +63,10 @@ case $command_name in
timeout 5 chg verify 2>&1
;;

invalidatedircache)
# Do nothing; the ls before the case was the whole point of this command
;;

*)
# Env var PYTHONUNBUFFERED required for commands like verify and recover, so that output can stream back to the project page
PYTHONUNBUFFERED=1 chg $command_name 2>&1
Expand Down

0 comments on commit cfc5a43

Please sign in to comment.