Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b2448510ac | |||
| 75610e3f55 | |||
| 5032166106 | |||
| 76a042d663 |
@@ -106,6 +106,8 @@ public sealed class LazyBrowseNodeTests
|
|||||||
new RpcException(new Status(StatusCode.NotFound, "Parent not found"))));
|
new RpcException(new Status(StatusCode.NotFound, "Parent not found"))));
|
||||||
|
|
||||||
await Assert.ThrowsAsync<MxGatewayException>(async () => await roots[0].ExpandAsync());
|
await Assert.ThrowsAsync<MxGatewayException>(async () => await roots[0].ExpandAsync());
|
||||||
|
Assert.False(roots[0].IsExpanded);
|
||||||
|
Assert.Empty(roots[0].Children);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -375,7 +375,10 @@ func (c *GalaxyClient) browseChildrenInner(
|
|||||||
return nodes, nil
|
return nodes, nil
|
||||||
}
|
}
|
||||||
if _, dup := seen[pageToken]; dup {
|
if _, dup := seen[pageToken]; dup {
|
||||||
return nil, fmt.Errorf("mxgateway: galaxy browse children returned repeated page token %q", pageToken)
|
return nil, &GatewayError{
|
||||||
|
Op: "galaxy browse children",
|
||||||
|
Err: fmt.Errorf("repeated page token %q", pageToken),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
seen[pageToken] = struct{}{}
|
seen[pageToken] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -738,3 +738,30 @@ func TestGalaxyBrowseWithFilterForwardsToRequest(t *testing.T) {
|
|||||||
t.Fatal("HistorizedOnly = false, want true")
|
t.Fatal("HistorizedOnly = false, want true")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGalaxyBrowseChildrenRejectsRepeatedPageToken(t *testing.T) {
|
||||||
|
// Build a reply that carries a non-empty NextPageToken so browseChildrenInner
|
||||||
|
// will request a second page. Queue the same reply twice so the second response
|
||||||
|
// returns the same page token, triggering the duplicate-token guard.
|
||||||
|
page := buildBrowseReply(
|
||||||
|
[]*pb.GalaxyObject{obj(1, "Plant", true)},
|
||||||
|
[]bool{true},
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
page.NextPageToken = "1:abc:1"
|
||||||
|
|
||||||
|
fake := &fakeGalaxyServer{
|
||||||
|
browseChildrenReplies: []*pb.BrowseChildrenReply{page, page},
|
||||||
|
}
|
||||||
|
client, cleanup := newGalaxyBufconnClient(t, fake)
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
|
_, err := client.Browse(context.Background(), nil)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("Browse: error = nil, want repeated-page-token error")
|
||||||
|
}
|
||||||
|
var gwErr *GatewayError
|
||||||
|
if !errors.As(err, &gwErr) {
|
||||||
|
t.Fatalf("error type = %T, want *GatewayError; err = %v", err, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+21
@@ -203,6 +203,27 @@ final class GalaxyRepositoryClientTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void browseChildrenRejectsRepeatedPageToken() throws Exception {
|
||||||
|
// Queue the same BrowseChildrenReply twice with a non-empty NextPageToken.
|
||||||
|
// The client will request a second page and detect that the token repeats.
|
||||||
|
BrowseChildrenService service = new BrowseChildrenService();
|
||||||
|
BrowseChildrenReply repeatedReply = browseReply(
|
||||||
|
List.of(obj(1, "Plant", true)),
|
||||||
|
List.of(true),
|
||||||
|
1L,
|
||||||
|
"1:abc:1");
|
||||||
|
service.replies.add(repeatedReply);
|
||||||
|
service.replies.add(repeatedReply);
|
||||||
|
|
||||||
|
try (InProcessGalaxy g = InProcessGalaxy.start(service, new AtomicReference<>());
|
||||||
|
GalaxyRepositoryClient client = g.client("")) {
|
||||||
|
MxGatewayException error = assertThrows(MxGatewayException.class, client::browse);
|
||||||
|
|
||||||
|
assertTrue(error.getMessage().contains("repeated page token"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void watchDeployEventsReceivesEventsInOrder() throws Exception {
|
void watchDeployEventsReceivesEventsInOrder() throws Exception {
|
||||||
DeployEvent first = DeployEvent.newBuilder()
|
DeployEvent first = DeployEvent.newBuilder()
|
||||||
|
|||||||
@@ -348,21 +348,21 @@ public sealed class GalaxyRepositoryGrpcService(
|
|||||||
{
|
{
|
||||||
throw new RpcException(new Status(
|
throw new RpcException(new Status(
|
||||||
StatusCode.InvalidArgument,
|
StatusCode.InvalidArgument,
|
||||||
"DiscoverHierarchy page_token is invalid."));
|
"page_token is invalid."));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sequence != currentSequence)
|
if (sequence != currentSequence)
|
||||||
{
|
{
|
||||||
throw new RpcException(new Status(
|
throw new RpcException(new Status(
|
||||||
StatusCode.InvalidArgument,
|
StatusCode.InvalidArgument,
|
||||||
"DiscoverHierarchy page_token is stale."));
|
"page_token is stale."));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.Equals(parts[1], currentFilterSignature, StringComparison.Ordinal))
|
if (!string.Equals(parts[1], currentFilterSignature, StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
throw new RpcException(new Status(
|
throw new RpcException(new Status(
|
||||||
StatusCode.InvalidArgument,
|
StatusCode.InvalidArgument,
|
||||||
"DiscoverHierarchy page_token does not match the current filters."));
|
"page_token does not match the current filters."));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new PageToken(sequence, parts[1], offset);
|
return new PageToken(sequence, parts[1], offset);
|
||||||
|
|||||||
Reference in New Issue
Block a user