diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 4821110ff5..bac3b514d6 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,7 +1,22 @@ ### Proposed changes -Describe the use case and detail of the change. If this PR addresses an issue on GitHub, make sure to include a link to that issue here in this description (not in the title of the PR). + +Write a clear and concise description that helps reviewers understand the purpose and impact of your changes. Use the +following format: + +Problem: Give a brief overview of the problem or feature being addressed. + +Solution: Explain the approach you took to implement the solution, highlighting any significant design decisions or +considerations. + +Testing: Describe any testing that you did. + +Please focus on (optional): If you any specific areas where you would like reviewers to focus their attention or provide +specific feedback, add them here. + +Closes #ISSUE ### Checklist + Before creating a PR, run through this checklist and mark each as complete. - [ ] I have read the [CONTRIBUTING](https://github.com/nginxinc/nginx-kubernetes-gateway/blob/main/CONTRIBUTING.md) doc diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0e854e6f52..a1c797ea41 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,7 @@ # Contributing Guidelines -The following is a set of guidelines for contributing to NGINX Kubernetes Gateway. We really appreciate that you are considering contributing! +The following is a set of guidelines for contributing to NGINX Kubernetes Gateway. We really appreciate that you are +considering contributing! #### Table Of Contents @@ -10,9 +11,13 @@ The following is a set of guidelines for contributing to NGINX Kubernetes Gatewa [Contributing](#contributing) +* [Issues and Discussions](#issues-and-discussions) +* [Development Guide](#development-guide) + [Style Guides](#style-guides) - * [Git Style Guide](#git-style-guide) - * [Go Style Guide](#go-style-guide) + +* [Git Style Guide](#git-style-guide) +* [Go Style Guide](#go-style-guide) [Code of Conduct](CODE_OF_CONDUCT.md) @@ -20,15 +25,16 @@ The following is a set of guidelines for contributing to NGINX Kubernetes Gatewa ## Ask a Question -To ask a question please use [Github Discussions](https://github.com/nginxinc/nginx-kubernetes-gateway/discussions). +To ask a question, use [Github Discussions](https://github.com/nginxinc/nginx-kubernetes-gateway/discussions). -[NGINX Community Slack](https://community.nginx.org/joinslack) has a dedicated channel for this project -- `#nginx-kubernetes-gateway`. +[NGINX Community Slack](https://community.nginx.org/joinslack) has a dedicated channel for this +project -- `#nginx-kubernetes-gateway`. -Please reserve GitHub issues for feature requests and bugs rather than general questions. +Reserve GitHub issues for feature requests and bugs rather than general questions. ## Getting Started -Follow our [Installation Instructions](README.md#run-nginx-gateway) to get the NGINX Kubernetes Gateway up and running. +Follow our [Installation Instructions](/docs/installation.md) to get the NGINX Kubernetes Gateway up and running. ### Project Structure @@ -40,52 +46,80 @@ Follow our [Installation Instructions](README.md#run-nginx-gateway) to get the N * Deployment yaml files are found at `deploy/` * External APIs, clients, and SDKs can be found under `pkg/` * We use [Go Modules](https://github.com/golang/go/wiki/Modules) for managing dependencies. -* We use [Ginkgo](https://onsi.github.io/ginkgo/) and [Gomega](https://onsi.github.io/gomega/) for our BDD style unit tests. +* We use [Ginkgo](https://onsi.github.io/ginkgo/) and [Gomega](https://onsi.github.io/gomega/) for our BDD style unit + tests. ## Contributing -### Report a Bug +### Issues and Discussions + +#### Open a Discussion + +If you have any questions, ideas, or simply want to engage in a conversation with the community and maintainers, we +encourage you to open a [discussion](https://github.com/nginxinc/nginx-kubernetes-gateway/discussions) on GitHub. We +highly recommend that you open a discussion about a potential enhancement before opening an issue. This enables the +maintainers to gather valuable insights regarding the idea and its use cases, while also giving the community an +opportunity to provide valuable feedback. + +#### Report a Bug -To report a bug, open an issue on GitHub with the label `bug` using the available bug report issue template. Please ensure the issue has not already been reported. +To report a bug, open an issue on GitHub with the label `bug` using the available bug report issue template. Before +reporting a bug, make sure the issue has not already been reported. -### Suggest an Enhancement +#### Suggest an Enhancement -To suggest an enhancement, please create an issue on GitHub with the label `enhancement` using the available feature issue template. +To suggest an enhancement, create an issue on GitHub with the label `proposal` using the available feature issue +template. -### Open a Pull Request +#### Issue lifecycle -* Fork the repo, create a branch, submit a PR when your changes are tested and ready for review -* Fill in [our pull request template](.github/PULL_REQUEST_TEMPLATE.md) +When an issue or PR is created, it will be triaged by the maintainers and assigned a label to indicate the type of issue +it is (bug, feature request, etc) and to determine the milestone. See the [Issue Lifecycle](/ISSUE_LIFECYCLE.md) document +for more information. -> **Note** -> -> If you’d like to implement a new feature, please consider creating a feature request issue first to start a discussion about the feature. +### Development Guide -### Issue lifecycle +Before beginning development, familiarize yourself with the following documents: -* When an issue or PR is created, it will be triaged by the core development team and assigned a label to indicate the type of issue it is (bug, feature request, etc) and to determine the milestone. Please see the [Issue Lifecycle](ISSUE_LIFECYCLE.md) document for more information. +- [Developer Quickstart](/docs/developer/quickstart.md): This guide provides a quick and easy walkthrough of setting up + your development environment and executing tasks required when submitting a pull request. +- [Branching and Workflow](/docs/developer/branching-and-workflow.md): This document outlines the project's specific + branching and workflow practices, including instructions on how to name a branch. +- [Implement a Feature](/docs/developer/implementing-a-feature.md): A step-by-step guide on how to implement a feature or + bug. +- [Testing](/docs/developer/testing.md): The project's testing guidelines, includes both unit testing and manual testing + procedures. This document explains how to write and run unit tests, and how to manually verify changes. +- [Pull Request Guidelines](/docs/developer/pull-request.md): A guide for both pull request submitters and reviewers, + outlining guidelines and best practices to ensure smooth and efficient pull request processes. ## Style Guides ### Git Style Guide -* Keep a clean, concise and meaningful git commit history on your branch, rebasing locally and squashing before submitting a PR -* Follow the guidelines of writing a good commit message as described [here](https://chris.beams.io/posts/git-commit/) and summarized in the next few points +* Keep a clean, concise and meaningful git commit history on your branch, rebasing locally and squashing before + submitting a PR +* Follow the guidelines of writing a good commit message as described [here](https://chris.beams.io/posts/git-commit/) + and summarized in the next few points * In the subject line, use the present tense ("Add feature" not "Added feature") * In the subject line, use the imperative mood ("Move cursor to..." not "Moves cursor to...") * Limit the subject line to 72 characters or less * Reference issues and pull requests liberally after the subject line - * Add more detailed description in the body of the git message (`git commit -a` to give you more space and time in your text editor to write a good message instead of `git commit -am`) + * Add more detailed description in the body of the git message (`git commit -a` to give you more space and time in + your text editor to write a good message instead of `git commit -am`) ### Go Style Guide -* Run `gofmt` over your code to automatically resolve a lot of style issues. Most editors support this running automatically when saving a code file. +* Run `gofmt` over your code to automatically resolve a lot of style issues. Most editors support this running + automatically when saving a code file. * Run `go lint` and `go vet` on your code too to catch any other issues. * Follow this guide on some good practice and idioms for Go - https://github.com/golang/go/wiki/CodeReviewComments -* To check for extra issues, install [golangci-lint](https://github.com/golangci/golangci-lint) and run `make lint` or `golangci-lint run` +* To check for extra issues, install [golangci-lint](https://github.com/golangci/golangci-lint) and run `make lint` + or `golangci-lint run` ## Contributor License Agreement -Individuals or business entities who contribute to this project must have completed and submitted the [F5® Contributor License Agreement](F5ContributorLicenseAgreement.pdf) prior to their code submission being included in this project. -To submit, please print out the [F5® Contributor License Agreement](F5ContributorLicenseAgreement.pdf), fill in the required sections, sign, scan, and send executed CLA to kubernetes@nginx.com. -Please include your github handle in the CLA email. +Individuals or business entities who contribute to this project must have completed and submitted +the [F5® Contributor License Agreement](F5ContributorLicenseAgreement.pdf) prior to their code submission being included +in this project. To submit, print out the [F5® Contributor License Agreement](F5ContributorLicenseAgreement.pdf), fill +in the required sections, sign, scan, and send executed CLA to kubernetes@nginx.com. Make sure to include your github +handle in the CLA email. diff --git a/docs/developer/branching-and-workflow.md b/docs/developer/branching-and-workflow.md new file mode 100644 index 0000000000..aec096b540 --- /dev/null +++ b/docs/developer/branching-and-workflow.md @@ -0,0 +1,50 @@ +# Branching and Workflow + +NKG is an open source and public repository; our goal is to keep the number of branches in the repository to a minimum: +the main branch, release branches and long-term feature branches. + +Internal developers and external contributors will follow a fork and merge process. Each contributor should fork the +repo to their own space; branch, experiment, develop and prepare a pull request (PR) to merge their work into NKG’s main +branch. This way ephemeral developer branches will remain outside the main repository. + +Below is an example of following the merge and fork process. Developer Alice: + +- Forks `github.com/nginxinc/nginx-kubernetes-gateway` → `github.com//nginx-kubernetes-gateway` +- Adds upstream: + ```shell + git remote add upstream git@github.com:nginxinc/nginx-kubernetes-gateway.git + ``` +- Alice lists all of her configured remotes: + ```shell + git remote -v + ``` + Which shows the following: + ```text + origin git@github.com:/nginx-kubernetes-gateway.git (fetch) + origin git@github.com:/nginx-kubernetes-gateway.git (push) + upstream git@github.com:nginxinc/nginx-kubernetes-gateway.git (fetch) + upstream git@github.com:nginxinc/nginx-kubernetes-gateway.git (push) + ``` +- Alice develops a feature or bugfix - using as many ephemeral branches as she needs. +- Alice creates a + PR `github.com//nginx-kubernetes-gateway:feature/some-feature` → `github.com/nginxinc/nginx-kubernetes-gateway:main` +- Alice keeps her fork up to date by running: + ```shell + git pull upstream main + ``` + This will sync her local main branch with the main branch of the project's repo. + +## Branch Naming Conventions + +To maintain consistency and facilitate proper labeling of pull requests (PRs), we follow specific branch naming +conventions. Each branch should contain a prefix that accurately describes the purpose of the PR. The prefixes align +with the labels defined in the [labeler](/.github/labeler.yml) file, which are used to create release notes. + +For example, if you are working on a bug fix, name your branch starting with `bug/` or `fix/`, followed by a descriptive +name of the bug you are fixing. + +To ensure correct labeling of your PRs, please use the appropriate prefix from the predefined list when naming your +branches. This practice helps maintain consistent labeling and allows for the automated generation of accurate release +notes. + +For a comprehensive list of labels and prefixes, please refer to the [labeler](/.github/labeler.yml) file. diff --git a/docs/developer/code-review-pyramid.jpeg b/docs/developer/code-review-pyramid.jpeg new file mode 100644 index 0000000000..f670f8bd92 Binary files /dev/null and b/docs/developer/code-review-pyramid.jpeg differ diff --git a/docs/developer/implementing-a-feature.md b/docs/developer/implementing-a-feature.md new file mode 100644 index 0000000000..c797737cf3 --- /dev/null +++ b/docs/developer/implementing-a-feature.md @@ -0,0 +1,68 @@ +# Implementing a Feature + +This document provides guidance on implementing new features in the project. Follow the recommended steps and best +practices to ensure a successful feature development process. + +> **Note** +> +> If you’d like to implement a new feature, please open a discussion about the feature before creating an issue or opening a PR. + +1. **Assign yourself to the GitHub issue for the feature**: Each feature must have a corresponding GitHub issue to track + its progress. +2. **Post any questions or comments about the feature on the corresponding issue**: This allows for better tracking and + visibility. If any discussions regarding the issue occur outside the issue thread, provide a summary of the + conversation as a comment on the issue itself. This ensures that all relevant information and discussions are + consolidated in one place for easy reference. +3. **Fork the repo**: NKG follows a fork workflow, which you can learn more about in + the [branching and workflow](/docs/developer/branching-and-workflow.md) documentation. +4. **Branch**: Create a branch following + the [naming conventions](/docs/developer/branching-and-workflow.md#branch-naming-conventions). +5. **Make changes**: Make the necessary changes for the feature. +6. **Consider opening a draft PR**: If your feature involves substantial architecture changes, or you would like to + receive early feedback, consider opening a draft PR and requesting reviews from the maintainers. Draft PRs are an + effective means to solicit feedback and ensure that major architectural changes align with the project's goals and + standards. +7. **Add or update unit tests** All features **must** be accompanied by unit tests that verify the functionality. Make + sure to thoroughly test the different scenarios and edge cases related to the feature to ensure robustness and + reliability. Additionally, open the code coverage report to ensure that the code you added has sufficient test + coverage. For instructions on writing and running unit tests, refer to + the [testing](/docs/developer/testing.md#unit-test-guidelines) documentation. +8. **Manually verify your changes**: Refer to the [manual testing](/docs/developer/testing.md#manual-testing) section of + the testing documentation for instructions on how to manually test your changes. +9. **Update any relevant documentation**: Here are some guidelines for updating documentation: + - **Gateway API Feature**: If you are implementing a Gateway API feature, make sure to update + the [Gateway API Compatibility](/docs/gateway-api-compatibility.md) documentation. + - **New Use Case:** If your feature introduces a new use case, add an example of how to use it in + the [examples](/examples) directory. This example will help users understand how to leverage the new feature. + - **Installation Changes**: If your feature involves changes to the installation process of NKG, update + the [installation](/docs/installation.md) documentation. + - **Command-line Changes**: If your feature introduces or changes a command-line flag or subcommand, update + the [cli help](/docs/cli-help.md) documentation. + - **Other Documentation Updates**: For any other changes that affect the behavior, usage, or configuration of NKG, + review the existing documentation and update it as necessary. Ensure that the documentation remains accurate and + up to date with the latest changes. +10. **Lint code**: See the [run the linter](/docs/developer/quickstart.md#run-the-linter) section of the quickstart + guide for instructions. +11. **Open pull request**: Open a pull request targeting the `main` branch of + the [nginx-kubernetes-gateway](https://github.com/nginxinc/nginx-kubernetes-gateway/tree/main) repository. The + entire `nginx-kubernetes-gateway` group will be automatically requested for review. If you have a specific or + different reviewer in mind, you can request them as well. Refer to + the [pull request](/docs/developer/pull-request.md) documentation for expectations and guidelines. +12. **Obtain the necessary approvals**: Work with code reviewers to maintain the required number of approvals. +13. **Squash and merge**: Squash your commits locally, or use the GitHub UI to squash and merge. Only one commit per + pull request should be merged. Make sure the first line of the final commit message includes the pull request + number. For example, Fix supported gateway conditions in compatibility doc (#674). + > **Note**: + When you squash commits, make sure to not include any commit messages related to the code review + (for example, Fixed a typo). If you changed the code as a result of the code review in way that the original commit message no longer describes it well, make sure to update the message. + + + +## Fixing a Bug + +When fixing a bug, follow the same process as [implementing a feature](#implementing-a-feature) with one additional +requirement: + +All bug fixes should be reproduced with a unit test before submitting any code. Once the bug is reproduced in a unit +test, make the necessary code changes to address the issue and ensure that the unit test passes successfully. This +systematic approach helps ensure that the bug is properly understood, effectively resolved, and prevents regression. diff --git a/docs/developer/pull-request.md b/docs/developer/pull-request.md new file mode 100644 index 0000000000..9849cbf47e --- /dev/null +++ b/docs/developer/pull-request.md @@ -0,0 +1,102 @@ +# Pull Request (PR) Guidelines + +## Submitter Guidelines + +- Fill in [our pull request template](/.github/PULL_REQUEST_TEMPLATE.md). +- Make sure to include the issue number in the PR description to automatically close the issue when the PR mergers. + See [Closing Issues via Pull Requests](https://github.blog/2013-05-14-closing-issues-via-pull-requests/) for details. +- For significant changes, break your changes into a logical series of smaller commits. By approaching the changes + incrementally, it becomes easier to comprehend and review the code. +- Use your best judgement when resolving comments. Simple, unambiguous comments should be resolved by the submitter, + this prioritizes speed and efficacy. For larger changes, for example, when updating logic and design, the resolution + should be left for the reviewer’s approval or continued discussion. +- If a discussion grows too long - more than a handful (3 - 5) back and forth responses, consider moving the discussion + to a more real-time platform: Slack, Zoom, Phone, In-person. Do this to clear misunderstandings or whiteboard + improvements. Whenever the conversation has moved to a different platform and found a conclusion, the decision and + resolution MUST be updated in the review, for instance, + + ```text + Comment: + + Spoke offline, decided to move A to package B. Rewrite tests and API docs. + ``` + +- When pushing code review changes, it's important to provide clear information to the reviewer. Here are a couple of + guidelines to follow: + - Commit each code review change individually. + - Use descriptive commit messages that accurately describe the change made, making it easy for the reviewer to + understand the purpose of the change. +- When approved, and all review comments have been resolved; squash commits to a single commit. Follow + the [Commit Message Format](#commit-message-format) guidelines when writing the final commit. + +## Reviewer Guidelines + +- As a reviewer, you bear the ultimate responsibility for the resolution of the comment. If not resolved, please + follow-up in a timely manner with acceptance of the solution and explanation. +- Do your best to review in a timely manner. However, code reviews are time-consuming; maximize their benefit by + focusing on what’s highest value. This code review pyramid outlines a reasonable shorthand: + ![Code Review Pyramid](code-review-pyramid.jpeg) +- Always review for: design, API semantics, [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) and + maintainability practices, bugs and quality, efficiency and correctness. +- Code review checklist: + - Do any changes need to made in documentation? + - Do public docs need updating? + - Have internal workflow and informational docs been impacted? + - Are there unit tests for the change? + - If the change is a bug fix, has a unit test been added or modified that catches the bug? All bug fixes should + be reproduced with a unit test before submitting any code. Then the code should be fixed so that the unit test + passes. + - If the change is a feature or new functionality. The expectation is to include a reasonable set of unit tests + which exercise positive and negative cases. + - Is this change backwards compatible? Is it causing breaking behavior? + - Are there any [Comment Tags](#comment-tags) in the change? + +## Commit Message Format + +The commit message for your final commit should use a consistent format: + +```text + + +Problem: Brief description of the problem. The “why”. + +Solution: Detailed description of the solution. Try to refrain from pseudo-code. Describe some of the analysis, thought +process, and outline what was done. Think of a newcomer coming across this two years hence. + +Testing (optional): Description of tests that were run to exercise the solutions (unit tests, system tests, +reproductions, etc.) + +``` + +Here's an example: + +```text +Make event stream handle large events + +Problem: The event stream would choke on events larger than 1K. This caused events to be silently dropped, and affected +all downstream consumers. + +Solution: Removed upper limit on event size. Also, added an error handler to warn when events are being dropped for any +reason. + +Added unit tests for events up to 1MB. +``` + +> **Note** +> Do not put any customer identifying information in message. Say “a customer found…”, NOT “ACME Corp found…”. If customer generated data is included it must be redacted for any PII (or identifying information). This includes IPs, ports, names of applications and objects, and URL paths. If customers volunteered this information, do not propagate it externally. + +For additional help on writing good commit messages, see this [article](https://cbea.ms/git-commit/). + +# Comment Tags + +We use the comment tags FIXME and TODO. + +A TODO is a developer note-to-self. TODOs _MUST_ be fixed before merging. + +A FIXME is for things that should be fixed in the future. If FIXMEs cannot be addressed before merging, they can be +merged, but they _MUST_ include your username and a link to the issue. For example: + +```go +// FIXME(username): This is currently a hack to work around known issue X. +// Issue will remove need for this work around. +``` diff --git a/docs/developer/quickstart.md b/docs/developer/quickstart.md new file mode 100644 index 0000000000..53f5c07821 --- /dev/null +++ b/docs/developer/quickstart.md @@ -0,0 +1,104 @@ +# Development Quickstart + +This guide will assist you in setting up your development environment for NGINX Kubernetes Gateway, covering the steps +to build, install, and execute tasks necessary for submitting pull requests. By following this guide, you'll have a +fully prepared development environment that allows you to contribute to the project effectively. + +## Setup Your Development Environment + +Follow these steps to set up your development environment. + +1. Install: + - [Go](https://golang.org/doc/install) + - [Docker](https://docs.docker.com/get-docker/) v18.09+ + - [Kind](https://kind.sigs.k8s.io/docs/user/quick-start/) + - [git](https://git-scm.com/) + - [GNU Make](https://www.gnu.org/software/software.html) + - [fieldalignment](https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/fieldalignment): + + ```shell + go install golang.org/x/tools/go/analysis/passes/fieldalignment/cmd/fieldalignment@latest + ``` + +2. [Fork the project repository](https://github.com/nginxinc/nginx-kubernetes-gateway/fork) +3. Clone your repository, and install the project dependencies: + + ```shell + git clone https://github.com//nginx-kubernetes-gateway.git + cd nginx-kubernetes-gateway + make deps + ``` + +## Build the Binary and Image + +### Build the Binary + +To build the binary, run the make build command from the project's root directory: + +```shell +make build +``` + +This command will build the binary and output it to the `/build/.out` directory. + +### Build the Image + +To build an NGINX Kubernetes Gateway container image from source run the following make command: + +```shell +make TAG=$(whoami) container +``` + +This will build the docker image and tag it with your user ID, e.g. `docker.io/library/nginx-kubernetes-gateway:user` + +## Deploy on Kind + +1. Create a `kind` cluster: + + ```shell + make create-kind-cluster + ``` + +2. Build the NKG image and load it onto your `kind` cluster: + + ```shell + make TAG=$(whoami) container + kind load docker-image docker.io/library/nginx-kubernetes-gateway:$(whoami) + ``` + +3. Modify the image name and image pull policy for the `nginx-gateway` container in the + NKG [deployment manifest](/deploy/manifests/nginx-gateway.yaml). Set the image name to the image you built in + the previous step and the image pull policy to `Never`. Once the changes are made, follow + the [installation instructions](/docs/installation.md) to install NKG on your `kind` cluster. + + Alternatively, you can update the image name and pull policy by using the following command when applying + `nginx-gateway.yaml`: + + ```shell + cat deploy/manifests/nginx-gateway.yaml | sed "s|image: ghcr.io/nginxinc/nginx-kubernetes-gateway.*|image: docker.io/library/nginx-kubernetes-gateway:|" | sed "s|imagePullPolicy: Always|imagePullPolicy: Never|" | kubectl apply -f - + ``` + +### Run Examples + +To make sure NKG is running properly, try out the [examples](/examples). + +## Run the Unit Tests + +To run all the unit tests, run the make unit-test command from the project's root directory: + +```shell +make unit-test +``` + +For more details on testing, see the [testing](/docs/developer/testing.md) documentation. + +## Run the Linter + +To lint the code, run the following make command from the project's root directory: + +```shell +make lint +``` + +> **Note** +> fieldalignment errors can be fixed by running: `fieldalignment -fix ` diff --git a/docs/developer/testing.md b/docs/developer/testing.md new file mode 100644 index 0000000000..2de781e6a4 --- /dev/null +++ b/docs/developer/testing.md @@ -0,0 +1,92 @@ +# Testing + +This document provides guidelines for testing, including instructions on running the unit tests, accessing the code +coverage report, and performing manual testing. By following these guidelines, you will gain a thorough understanding of +the project's approach to unit testing, enabling you to ensure code quality, validate functionality, and maintain robust +test coverage. + +## Unit Test Guidelines + +In our testing approach, we employ a combination of Behavior-Driven Development (BDD) style tests and traditional unit +tests. The choice of testing style depends on the nature of the code being tested. Here's a breakdown of our testing +practices: + +**All exported interfaces must be covered by BDD style tests**: We use the [Ginkgo](https://onsi.github.io/ginkgo/) +testing framework, which enables us to write expressive and readable tests that focus on the behavior of our code. +Additionally, we use the [Gomega](https://onsi.github.io/gomega/) matcher library to provide powerful assertions and +expectations within our BDD style tests. + +**Most testing should be done at the exported interface layer**: By writing tests at the exported interface layer, we +ensure that the tests remain decoupled from the internal implementation details. This allows us to refactor and modify +the implementation of the interface without needing to extensively update the tests. It promotes flexibility and +maintainability in our codebase. + +**Use standard unit tests to cover gaps**: While we primarily focus on testing at the exported interface layer, we +acknowledge the importance of comprehensive test coverage. If we identify areas that require additional testing or if +the exported interface layer doesn't provide sufficient coverage, we typically use unit tests to cover these gaps. This +ensures that critical code paths and edge cases are thoroughly tested. We still use +the [Gomega](https://onsi.github.io/gomega/) matcher library for assertions within these tests. + +**Use table-driven tests**: When testing multiple cases for a single function or method, we prefer to use table-driven +tests. For BDD style tests, use [DescribeTable](https://onsi.github.io/ginkgo/#table-specs) and for standard unit tests, +use [subtests](https://go.dev/blog/subtests). + +**Generate test mocks**: To facilitate the generation of mocks for testing, we use +the [Counterfeiter](https://github.com/maxbrunsfeld/counterfeiter) tool. Counterfeiter helps us create mock +implementations of internal and public interfaces, allowing us to isolate and control dependencies during testing. It +simplifies the process of mocking and stubbing, making our tests more robust and flexible. + +By combining BDD style tests, unit tests, and mock generation, we aim to achieve a comprehensive and maintainable +testing strategy. This approach enables us to ensure the correctness, reliability, and flexibility of our codebase while +promoting efficient refactoring and continuous development. + +### Running the Unit Tests + +To run the unit tests, run the make unit-test command from the project's root directory: + +```shell +make unit-test +``` + +This command runs the unit tests with the `-race` flag, enabling the detection of potential data races. + +#### Viewing Code Coverage Report + +The unit tests generate a code coverage file named `cover.html` in the project's root directory. To view the code +coverage report, open the `cover.html` file in your browser. The report provides insights into which parts of the code +are covered by the tests and helps identify areas that may require additional testing. + +## Manual Testing + +To ensure the quality and correctness of your changes, it is essential to perform manual testing in a Kubernetes +cluster. Manual testing helps validate the functionality and behavior of your changes in a real-world environment. +Follow the steps below for manual testing: + +1. Follow the instructions to [deploy on kind](/docs/developer/quickstart.md#deploy-on-kind). +2. Test your changes. Make sure to check the following: + - Logs of the `nginx-gateway` container. Look out for unexpected error logs or panics. + ```shell + kubectl logs -n nginx-gateway -l app=nginx-gateway + ``` + - Logs of the `nginx` container. Look for unexpected error logs and verify the access logs are correct. + ```shell + kubectl logs -n nginx-gateway -l app=nginx + ``` + - The generated nginx config. Make sure it's correct. + ```shell + kubectl exec -it -n nginx-gateway -c nginx -- nginx -T + ``` + - The statuses of the Gateway API Resources. Make sure they look correct. + ```shell + kubectl describe + ``` + - NGINX proxies traffic successfully (when applicable). + - [Examples](/examples) work correctly. This will ensure that your changes have not introduced any regressions. + + +> **Note** +> +> Don't limit yourself to happy path testing. Make an effort to cover various scenarios, including edge cases and potential error conditions. By testing a wide range of scenarios, you can uncover hidden issues and ensure the robustness of your changes. + +Performing manual testing helps guarantee the stability, reliability, and effectiveness of your changes before +submitting them for review and integration into the project.