Skip to content
This repository was archived by the owner on Apr 27, 2026. It is now read-only.

Expand combinatorial testing of HTTP parser#3166

Merged
jonsequitur merged 6 commits into
dotnet:mainfrom
jonsequitur:combinatorial-testing-for-diagnostics-4
Sep 13, 2023
Merged

Expand combinatorial testing of HTTP parser#3166
jonsequitur merged 6 commits into
dotnet:mainfrom
jonsequitur:combinatorial-testing-for-diagnostics-4

Conversation

@jonsequitur

@jonsequitur jonsequitur commented Sep 8, 2023

Copy link
Copy Markdown
Contributor

This PR adds more combinatorial testing and fixes a number of bugs discovered in the process, with scenario-specific tests added in each case. I've removed the HttpBodySeparatorNode concept.

It also contains a few small unrelated changes from API review.

public string? GetDefaultKernelName()
{
if (TryGetKernelInfoFromMetadata(Metadata, out var kernelInfo))
// FIX: (GetDefaultKernelName) remove from public API

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you intend to leave this change in the current PR?

@jonsequitur
jonsequitur force-pushed the combinatorial-testing-for-diagnostics-4 branch from 7ed0728 to ed81852 Compare September 8, 2023 20:43

if (ParseRequestSeparator() is { } separatorNode)
{
// FIX: (Parse) uncovered

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this something that will be fixed in a future PR?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's uncovered but removing it causes tests to fail, which points to a test gap but not to the code being superfluous. We can look into these examples during a group session. (Test-first approaches usually avoid this kind of uncertainty.)

}

private IEnumerable<HttpVariableDeclarationAndAssignmentNode>? ParseVariableDeclarations()
private static void AppendCommentsIfAny(List<HttpCommentNode> commentsToAppend, HttpSyntaxNode prependToNode)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prependToNode -> appendToNode (Or perhaps just change it to node in both functions).

commentsToAppend.Clear();
}

private static void PrependCommentsIfAny(List<HttpCommentNode> commentsToPrepend, HttpSyntaxNode prependToNode)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method looks identical to the one above except for the addBefore argument. Consider creating a single AddCommentsIfAny() method with an addBefore parameter.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method has been removed.

node.Add(ParseExpression());
node.Add(ParseExpressionEnd());
var expressionEnd = ParseExpressionEnd();
if (expressionEnd is not null)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious why is there a null check for the end of an expression but not for the expression itself?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found a bug via testing that drove this specific change.


if (IsComment())
{
// FIX: (ParseRequest) this looks suspect... test with a comment at the start of the request node?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this for a future PR?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potentially, yes. There's no need to hold a PR to fix unrelated pre-existing issues.

ConsumeCurrentTokenInto(node);
}

ParseTrailingWhitespace(node);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider: return PassTRailingWhitespace(node);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was considering removing the return values from these methods as it makes it ambiguous as to whether they return the original node.

return ParseTrailingTrivia(node);
ParseTrailingWhitespace(node);

return node;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider: return PassTRailingWhitespace(node);

@@ -759,15 +772,14 @@ private bool IsComment()
return false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: This line seems redundant since we already return false on line 775 below.

if (MoreTokens() && !IsRequestSeparator())
{
if (CurrentToken is { Kind: HttpTokenKind.Punctuation } and { Text: "#" })
if (CurrentToken is { Text: "#" })

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was also a question before the changes in the current PR, but it is unclear whether comments are allowed to start at the end of an existing line e.g.

myHeaderName: myHeaderValue // a comment
or
get https://www.host.com HTTP/1.1 # a comment

I think we disallow this at the moment. But it would be great to add (negative) tests for the above cases. We should probably also report errors like unexpected token "/" at position (*, *) in such cases.

}

var commentsToPrepend = new List<HttpCommentNode>();
if (ParseComment() is { } comment)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we would also fail to parse the comment if there is any whitespace before the # token (since ParseComment expects the current token to be #).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might depend on whether a previous call parsed the trailing whitespace.

For what it's worth, the old parser reports a diagnostic when there's whitespace on the line preceding the #.

@jonsequitur
jonsequitur force-pushed the combinatorial-testing-for-diagnostics-4 branch from ba9ae08 to 50f1cb6 Compare September 11, 2023 22:54

@shyamnamboodiripad shyamnamboodiripad left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving to unblock - will complete review later and we can address anything blocking in a follow up PR.

@jonsequitur
jonsequitur merged commit c13d287 into dotnet:main Sep 13, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants