Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Simple Event polling and create profile based testing #200

Merged
merged 10 commits into from
Jun 26, 2024

Conversation

The-Huginn
Copy link
Collaborator

  • Implement simple Event polling processor, which adjust the received events and fires those events
  • Implement simple testing framework for manual event firing - i.e. GitHubEventEmitter - new interface for firing events, our event polling processor)
  • Implement another testing framework for profile aware testing, between sse and manually fired events from polling
  • Rewrite tests to use profile aware testing

Future work:

  • Tests for event firing testing framework
  • Implement caching of events since last polling (currently we take only the last event and fire it) + tests

@The-Huginn The-Huginn requested a review from xstefank April 30, 2024 14:38
@The-Huginn The-Huginn force-pushed the event-polling branch 2 times, most recently from 7aec6ee to 106cd6b Compare May 2, 2024 06:49
@The-Huginn The-Huginn requested a review from petrberan May 2, 2024 10:34
* https://docs.github.com/en/rest/using-the-rest-api/github-event-types?apiVersion=2022-11-28
* and Events sent by GitHub SSE https://docs.github.com/en/webhooks/webhook-events-and-payloads
*/
private static final Map<GHEvent, Tuple2<String, Boolean>> typeToEventMap = Map.of(
Copy link
Member

Choose a reason for hiding this comment

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

maybe it would be better from maintainability and readability point of view to not use Tuple2

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

what would you like to see used instead?

Copy link
Member

Choose a reason for hiding this comment

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

Custom named wrapper.

@FunctionalInterface
public interface GitHubEventEmitter<T extends Throwable> {

void fire() throws T;
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need this since fire() method in EventPollingProcessor is scheduled?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

For the testing framework, so we can manually fire the events once everything is mocked.

Copy link
Member

Choose a reason for hiding this comment

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

If it's just for testing, maybe think if you can reuse automatic polling to stay more closely aligned with the original code.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think this single interface makes it much easier for testing, as otherwise how could we discover the correct beans?

@FunctionalInterface
public interface GitHubEventPreprocessor {
GitHubEventPreprocessor INSTANCE = new DefaultGitHubEventPreprocessor();
ObjectMapper objectMapper = new ObjectMapper();
Copy link
Member

Choose a reason for hiding this comment

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

We should reuse objectmapper if possible.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

it is static by default this way - in the interface. It's for this reason in the interface, so implementing classes can use it, such as PushEventPreprocessor does.

Copy link
Member

Choose a reason for hiding this comment

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

maybe then don't use fields in interfaces

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I believe this is a common practice, for reusing common objects or for providing default static implementation

PullRequestGitHubEventPayload::new);

pullRequestJson = TestModel
.setPullRequestJsonBuilderBuild(pullRequestJsonBuilder -> pullRequestJsonBuilder.action(SYNCHRONIZE));
Copy link
Member

Choose a reason for hiding this comment

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

setPullRequestJson

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sure, but note, it's rather the builder we provide there.

Copy link
Member

Choose a reason for hiding this comment

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

and you called it BuilderBuild? setPRJSonBuilder then

TestModel.given(mocks -> WildflyGitHubBotTesting.mockRepo(mocks, wildflyConfigFile, pullRequestJson))
.sseEventOptions(eventSenderOptions -> eventSenderOptions.payloadFromString(pullRequestJson.jsonString())
.event(GHEvent.PULL_REQUEST))
.pollingEventOptions(eventSenderOptions -> eventSenderOptions.eventFromPayload(pullRequestJson.jsonString()))
Copy link
Member

Choose a reason for hiding this comment

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

maybe we don't need to repeat it if it's same for sse and polling?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sure, I can add some default methods. I was just worried to not hide too many details from the user, such that there would be too much unnecessary "magic" happening in the testing framework.

Copy link
Member

Choose a reason for hiding this comment

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

magic is what we do to make the end user code easier

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This has been already done previously, please see here. Let me know, if it fits the needs

() -> SsePullRequestPayload.builder(TestConstants.VALID_PR_TEMPLATE_JSON),
PullRequestGitHubEventPayload::new);

pullRequestJson = TestModel.getPullRequestJson();
Copy link
Member

Choose a reason for hiding this comment

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

Just when I see this side to side, do you think that this new API is easier?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sure, I will provide more default methods. Also, after this PR I would like to open issue, about prettyfying the old school builder. I don't think for example we need to provide TestConstants.VALID_PR_TEMPLATE_JSON all the time, etc. Similar to what I did with PullRequestGitHubEventPayload.

.then().github(mocks -> {

TestModel.given(
mocks -> WildflyGitHubBotTesting.mockRepo(mocks, wildflyConfigFile, pullRequestJson, mockedContext))
Copy link
Member

Choose a reason for hiding this comment

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

We can probably simplify this later. Not in this PR.

.sseEventOptions(eventSenderOptions -> eventSenderOptions.payloadFromString(pullRequestReviewJson.jsonString())
.event(GHEvent.PULL_REQUEST_REVIEW))
.pollingEventOptions(
eventSenderOptions -> eventSenderOptions.eventFromPayload(pullRequestReviewJson.jsonString()))
Copy link
Member

Choose a reason for hiding this comment

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

This could be simplified now right?

@xstefank xstefank merged commit ab5aabe into wildfly:main Jun 26, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants