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

chore: add unit tests for utilities.sh #1948

Merged
merged 13 commits into from
Sep 5, 2023
Merged

Conversation

JoeWang1127
Copy link
Collaborator

@JoeWang1127 JoeWang1127 commented Aug 29, 2023

Fixes #1947 ☕️

The list of utility functions:

  • extract_folder_name*
  • remove_empty_files
  • mv_src_files
  • unzip_src_files
  • find_additional_protos_in_yaml*
  • search_additional_protos*
  • get_gapic_opts*
  • remove_grpc_version*
  • download_gapic_generator_pom_parent*
  • get_grpc_version*
  • get_protobuf_version*
  • download_tools
  • download_generator*
  • download_protobuf*
  • download_grpc_plugin*
  • download_from*
  • copy_from
  • download_fail

Functions with star (*) are tested in this PR.

@product-auto-label product-auto-label bot added the size: m Pull request size is medium. label Aug 29, 2023
@product-auto-label product-auto-label bot added size: l Pull request size is large. and removed size: m Pull request size is medium. labels Aug 30, 2023
@product-auto-label product-auto-label bot added size: xl Pull request size is extra large. and removed size: l Pull request size is large. labels Aug 30, 2023
@JoeWang1127 JoeWang1127 changed the title chore: add unit tests for generate_library.sh chore: add unit tests for utilities.sh Aug 30, 2023
@JoeWang1127 JoeWang1127 marked this pull request as ready for review August 30, 2023 18:30
@JoeWang1127 JoeWang1127 requested a review from a team as a code owner August 30, 2023 18:30
@@ -76,15 +76,15 @@ search_additional_protos() {

# get gapic options from .yaml and .json files from proto_path.
get_gapic_opts() {
gapic_config=$(find "${proto_path}" -type f -name "*gapic.yaml")
gapic_config=$(find "$proto_path" -type f -name "*gapic.yaml")
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Collaborator Author

@JoeWang1127 JoeWang1127 Aug 31, 2023

Choose a reason for hiding this comment

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

Thanks for the reference, I'll draft another PR to fix formatting issues.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks Tomo for sharing this! This is really helpful, I see a section regarding when to use shell which I think it's worth discussing more in our next meeting.

Copy link
Collaborator

@blakeli0 blakeli0 left a comment

Choose a reason for hiding this comment

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

Do you plan to have another PR for the unit testing of generate_library.sh?

library_generation/test/generate_library_unit_tests.sh Outdated Show resolved Hide resolved
library_generation/test/generate_library_unit_tests.sh Outdated Show resolved Hide resolved
@@ -76,15 +76,15 @@ search_additional_protos() {

# get gapic options from .yaml and .json files from proto_path.
get_gapic_opts() {
gapic_config=$(find "${proto_path}" -type f -name "*gapic.yaml")
gapic_config=$(find "$proto_path" -type f -name "*gapic.yaml")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks Tomo for sharing this! This is really helpful, I see a section regarding when to use shell which I think it's worth discussing more in our next meeting.

"$gapic_opts"
}

remove_grpc_version_test() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not directly related to the tests, I wonder why we have to remove the gRPC version manually, what made the differences? Separately, I think it might be good to keep the version for troubleshooting/informational purposes.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

When using bazel build, there's a "by gRPC proto compiler" at the beginning of *Grpc.java file. However, the annotation becomes "by gRPC proto compiler xxx" when using shell script, where xxx is the grpc version.

I use this function to remove the version number so that two files are totally identical.

Copy link
Collaborator

@blakeli0 blakeli0 Sep 1, 2023

Choose a reason for hiding this comment

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

I thought bazel build eventually calls the same gRPC proto compiler? If not, we need to understand what exactly caused the differences, as there could be more differences when generating other services.

Copy link
Collaborator Author

@JoeWang1127 JoeWang1127 Sep 1, 2023

Choose a reason for hiding this comment

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

I think bazel build download the gRPC proto compiler source code from github (defined here in gax/repository.bzl) and build from source.

In generate_library.sh, it download gPRC compiler executable from maven central. I don't know whether there are differences but the generated code are the same.

I haven't seen any code difference when generating other services and I'll add more libraries to the integration test to make sure the generated code is the same as bazel build.

I also post a question and hope someone from grpc team has the answer.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think bazel build download the gRPC proto compiler source code from github (defined here in gax/repository.bzl) and build from source.

Thanks, this makes sense! Since we were building from source, maybe there is no concept of version on main branch, let's see if anyone answers the question.

@JoeWang1127
Copy link
Collaborator Author

JoeWang1127 commented Aug 31, 2023

Do you plan to have another PR for the unit testing of generate_library.sh?

I think generate_library.sh is tested through the integration tests since it "hooks" everything.
The result is verified through googleapis-gen (and google-cloud-java later).

@blakeli0
Copy link
Collaborator

blakeli0 commented Sep 1, 2023

Do you plan to have another PR for the unit testing of generate_library.sh?

I think generate_library.sh is tested through the integration tests since it "hooks" everything. The result is verified through googleapis-gen (and google-cloud-java later).

Unit tests and Integration tests serve different purposes. Integration tests treat the script somewhat like a black box and make sure it works in a real life scenario. Unit tests treat the script as a white box and attempt to test every combinations with test data.
For example, we have logics to get protobuf version from gapic-generator-java if it is not specified, so we need to have test cases for both protobuf version is specified and is not specified, and technically we need to have two test cases for each if condition.
Now how do we achieve that may not be that simple. For the above case, we could have a test gapic-generator-java pom that has a different protobuf version than the specified protobuf version through the script. If we can achieve the same results(testing every combinations) through googleapis-gen integration tests, that works too, but I feel it may be more complicated.


# Helper functions, they shouldn't be called outside this file.
__assertEquals() {
expected=$1
Copy link
Contributor

Choose a reason for hiding this comment

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

go/shell-style#use-local-variables
Functions should declare their local variables with the local keyword. We have several functions (not only in this PR) around that are not following this style. cc: @blakeli0 @suztomo would it make sense to have a "styling up" PR to make our scripts more compliant with the guidelines?

Copy link
Contributor

Choose a reason for hiding this comment

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

go/shell-style#constants-environment-variables-and-readonly-variables
Another example, to have constants with upper case (e.g. SCRIPT_DIR instead of script_dir)

Copy link
Contributor

Choose a reason for hiding this comment

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

nvm, I saw at the end of the changes we have https://github.com/googleapis/sdk-platform-java/pull/1948/files#r1311724425 to address this!

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 plan to propose a PR to format code after merging this one.

download_generator_success_with_valid_version_test() {
download_generator "2.24.0"
__assertFileExists "gapic-generator-java-2.24.0.jar"
rm "gapic-generator-java-2.24.0.jar"
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can have an "afterEach" function that cleans up the downloaded jars/tars, even if they don't exist. It could even be useful for local development where I personally find it a bit hard to read dir contents after I call the scripts

Copy link
Contributor

@diegomarquezp diegomarquezp Sep 1, 2023

Choose a reason for hiding this comment

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

This could be expanded with a git status to confirm we don't have any unexpected untracked files that aren't deleted by such function

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not all tests have clean up actions so it's difficult to write a function and apply it after every test execution.

However, I'll think about it in the reformat PR.

@JoeWang1127
Copy link
Collaborator Author

Unit tests and Integration tests serve different purposes. Integration tests treat the script somewhat like a black box and make sure it works in a real life scenario. Unit tests treat the script as a white box and attempt to test every combinations with test data. For example, we have logics to get protobuf version from gapic-generator-java if it is not specified, so we need to have test cases for both protobuf version is specified and is not specified, and technically we need to have two test cases for each if condition. Now how do we achieve that may not be that simple. For the above case, we could have a test gapic-generator-java pom that has a different protobuf version than the specified protobuf version through the script. If we can achieve the same results(testing every combinations) through googleapis-gen integration tests, that works too, but I feel it may be more complicated.

Unit test should test against public APIs so I think we can test generate_library.sh with golden tests: fix the protos and gapic-generator-java version (protobuf and grpc version may or may not provide, but the version should be the same as in gapic-generator-java), verify the script can generate the same source code (compare with golden files). Also, I can write test cases with invalid version of generator, protbuf and grpc to verify generate_library.sh exits with non-zero code. WDYT?

@sonarqubecloud
Copy link

sonarqubecloud bot commented Sep 2, 2023

[gapic-generator-java-root] Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
No Duplication information No Duplication information

@sonarqubecloud
Copy link

sonarqubecloud bot commented Sep 2, 2023

[java_showcase_integration_tests] Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
No Duplication information No Duplication information

@sonarqubecloud
Copy link

sonarqubecloud bot commented Sep 2, 2023

[java_showcase_unit_tests] Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
No Duplication information No Duplication information

@blakeli0
Copy link
Collaborator

blakeli0 commented Sep 5, 2023

I can write test cases with invalid version of generator, protbuf and grpc to verify generate_library.sh exits with non-zero code

SGTM!

I think we can test generate_library.sh with golden tests: fix the protos and gapic-generator-java version (protobuf and grpc version may or may not provide, but the version should be the same as in gapic-generator-java), verify the script can generate the same source code (compare with golden files)

I like the idea, this is similar to the golden unit/integration tests in gapic-generator-java.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Do the content of these test files matter? If not or only partially matters, can we simplify the content to only what we need? In addition, it would be great if we can name these test files based on what we are testing, and/or add additional comments on each yaml to indicate what this testing yaml is for. e.g. Something like This yaml is only intended for testing search_additional_protos function with a yaml name search_additional_protos_scenario_xyz.yaml.

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 makes sense.

I'll change the name and contents of yaml files in the reformat PR.

Copy link
Collaborator

@blakeli0 blakeli0 left a comment

Choose a reason for hiding this comment

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

LGTM pending a question regarding the testing files. There are a few additional follow ups that need to be done(unit tests and golden tests for generate_library.sh, style change etc), but they don't have to completed as part of this PR.

@JoeWang1127 JoeWang1127 merged commit 6e9ef3f into main Sep 5, 2023
@JoeWang1127 JoeWang1127 deleted the chore/add-unit-tests branch September 5, 2023 17:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size: xl Pull request size is extra large.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Write unit tests for utility functions used in library generation
4 participants