Skip to content

Commit

Permalink
fix(cli): improving relative file detection for protobuf (#3091)
Browse files Browse the repository at this point in the history
* fix(cli): improving relative file detection for protobuf

* Update tests and validation

* fixing typo

* Fixed e2e test

* Update test

* Fixing test file
  • Loading branch information
danielbdias committed Aug 22, 2023
1 parent cd6fb6d commit 4fd1c42
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 1 deletion.
10 changes: 10 additions & 0 deletions cli/pkg/fileutil/path.go
Expand Up @@ -27,7 +27,11 @@ func LooksLikeFilePath(path string) bool {
return strings.HasPrefix(path, "./") ||
strings.HasPrefix(path, "../") ||
strings.HasPrefix(path, "/")
}

func LooksLikeRelativeFilePath(path string) bool {
return strings.HasPrefix(path, "./") ||
strings.HasPrefix(path, "../")
}

func IsFilePath(path string) bool {
Expand All @@ -48,3 +52,9 @@ func IsFilePath(path string) bool {
// otherwise the user also could send a directory by mistake
return info != nil && !info.IsDir()
}

func IsFilePathToRelativeDir(path, dir string) bool {
fullPath := filepath.Join(dir, path)

return IsFilePath(fullPath)
}
12 changes: 11 additions & 1 deletion cli/preprocessor/test.go
Expand Up @@ -48,7 +48,7 @@ func (t test) consolidateGRPCFile(input fileutil.File, test openapi.TestResource
}

definedPBFile := test.Spec.Trigger.Grpc.GetProtobufFile()
if !fileutil.LooksLikeFilePath(definedPBFile) {
if !t.isValidGrpcFilePath(definedPBFile, input.AbsDir()) {
t.logger.Debug("protobuf file is not a file path", zap.String("protobufFile", definedPBFile))
return test, nil
}
Expand All @@ -66,3 +66,13 @@ func (t test) consolidateGRPCFile(input fileutil.File, test openapi.TestResource

return test, nil
}

func (t test) isValidGrpcFilePath(grpcFilePath, testFile string) bool {
if fileutil.LooksLikeRelativeFilePath(grpcFilePath) {
// if looks like a relative file path, test if it exists
return fileutil.IsFilePathToRelativeDir(grpcFilePath, testFile)
}

// it could be an absolute file path, test it
return fileutil.IsFilePath(grpcFilePath)
}
38 changes: 38 additions & 0 deletions testing/cli-e2etest/testscenarios/test/apply_test_test.go
Expand Up @@ -89,4 +89,42 @@ func TestApplyTest(t *testing.T) {
assert.Equal("grpc", listTest.Spec.Trigger.Type)
assert.Equal(string(proto), listTest.Spec.Trigger.GRPCRequest.ProtobufFile)
})

t.Run("GRPC With Embedded Protobuf starting on comment", func(t *testing.T) {
// comments on first line on a embedded protobuf can be confused with a relative path

// instantiate require with testing helper
require := require.New(t)
assert := assert.New(t)

proto, err := os.ReadFile("./resources/api-with-comment.proto")
require.NoError(err)

// setup isolated e2e environment
env := environment.CreateAndStart(t)
defer env.Close(t)

cliConfig := env.GetCLIConfigPath(t)

// Given I am a Tracetest CLI user
// And I have my server recently created

// When I try to set up a new test
// Then it should be applied with success
testPath := env.GetTestResourcePath(t, "grpc-trigger-embedded-protobuf-with-comment")

result := tracetestcli.Exec(t, fmt.Sprintf("apply test --file %s", testPath), tracetestcli.WithCLIConfig(cliConfig))
helpers.RequireExitCodeEqual(t, result, 0)

// When I try to get a test
// Then it should return the test applied on the last step
result = tracetestcli.Exec(t, "get test --id create-pokemon-embedded", tracetestcli.WithCLIConfig(cliConfig))
helpers.RequireExitCodeEqual(t, result, 0)

listTest := helpers.UnmarshalYAML[types.TestResource](t, result.StdOut)
assert.Equal("Test", listTest.Type)
assert.Equal("create-pokemon-embedded", listTest.Spec.ID)
assert.Equal("grpc", listTest.Spec.Trigger.Type)
assert.Equal(string(proto), listTest.Spec.Trigger.GRPCRequest.ProtobufFile)
})
}
@@ -0,0 +1,38 @@
// This is a comment
syntax = "proto3";

option java_multiple_files = true;
option java_outer_classname = "PokeshopProto";
option objc_class_prefix = "PKS";

package pokeshop;

service Pokeshop {
rpc getPokemonList (GetPokemonRequest) returns (GetPokemonListResponse) {}
rpc createPokemon (Pokemon) returns (Pokemon) {}
rpc importPokemon (ImportPokemonRequest) returns (ImportPokemonRequest) {}
}

message ImportPokemonRequest {
int32 id = 1;
optional bool isFixed = 2;
}

message GetPokemonRequest {
optional int32 skip = 1;
optional int32 take = 2;
optional bool isFixed = 3;
}

message GetPokemonListResponse {
repeated Pokemon items = 1;
int32 totalCount = 2;
}

message Pokemon {
optional int32 id = 1;
string name = 2;
string type = 3;
bool isFeatured = 4;
optional string imageUrl = 5;
}
@@ -0,0 +1,60 @@
type: Test
spec:
id: create-pokemon-embedded
name: "Create Pokemon"
description: Create a single pokemon on Pokeshop
trigger:
type: grpc
grpc:
protobufFile: |
// This is a comment
syntax = "proto3";
option java_multiple_files = true;
option java_outer_classname = "PokeshopProto";
option objc_class_prefix = "PKS";
package pokeshop;
service Pokeshop {
rpc getPokemonList (GetPokemonRequest) returns (GetPokemonListResponse) {}
rpc createPokemon (Pokemon) returns (Pokemon) {}
rpc importPokemon (ImportPokemonRequest) returns (ImportPokemonRequest) {}
}
message ImportPokemonRequest {
int32 id = 1;
optional bool isFixed = 2;
}
message GetPokemonRequest {
optional int32 skip = 1;
optional int32 take = 2;
optional bool isFixed = 3;
}
message GetPokemonListResponse {
repeated Pokemon items = 1;
int32 totalCount = 2;
}
message Pokemon {
optional int32 id = 1;
string name = 2;
string type = 3;
bool isFeatured = 4;
optional string imageUrl = 5;
}
address: demo-rpc:8082
method: pokeshop.Pokeshop.createPokemon
request: |-
{
"name": "Pikachu",
"type": "eletric",
"isFeatured": true
}
specs:
- name: It calls Pokeshop correctly
selector: span[tracetest.span.type="rpc" name="pokeshop.Pokeshop/createPokemon" rpc.system="grpc" rpc.method="createPokemon" rpc.service="pokeshop.Pokeshop"]
assertions:
- attr:rpc.grpc.status_code = 0

0 comments on commit 4fd1c42

Please sign in to comment.