Rollforward w/fix of "Use json encoding for cquery ParseResult"

Previous commit: commit fcc53f992b.

Test: 1. use `TARGET_BUILD_VARIANT=userdebug TARGET_PRODUCT=aosp_arm64 build/bazel/ci/mixed_droid.sh` to verify no error occurred.
2. revise the test cases under request_type_test. 3. pass the test cases

Bug: 242587802
Change-Id: I7f70e62f7b6f42fa5f211772888040a0d07a710b
This commit is contained in:
Jason Wu
2022-09-21 15:10:18 +00:00
parent b2dce1ae5e
commit 07bb005b99
2 changed files with 48 additions and 120 deletions

View File

@@ -158,63 +158,30 @@ else:
# NOTE: It's OK if there's no ToC, as Soong just uses it for optimization # NOTE: It's OK if there's no ToC, as Soong just uses it for optimization
pass pass
returns = [ return json_encode({
outputFiles, "OutputFiles": outputFiles,
ccObjectFiles, "CcObjectFiles": ccObjectFiles,
sharedLibraries, "CcSharedLibraryFiles": sharedLibraries,
staticLibraries, "CcStaticLibraryFiles": staticLibraries,
includes, "Includes": includes,
system_includes, "SystemIncludes": system_includes,
headers, "Headers": headers,
rootStaticArchives, "RootStaticArchives": rootStaticArchives,
rootSharedLibraries, "RootDynamicLibraries": rootSharedLibraries,
[toc_file] "TocFile": toc_file
] })`
return "|".join([", ".join(r) for r in returns])`
} }
// ParseResult returns a value obtained by parsing the result of the request's Starlark function. // ParseResult returns a value obtained by parsing the result of the request's Starlark function.
// The given rawString must correspond to the string output which was created by evaluating the // The given rawString must correspond to the string output which was created by evaluating the
// Starlark given in StarlarkFunctionBody. // Starlark given in StarlarkFunctionBody.
func (g getCcInfoType) ParseResult(rawString string) (CcInfo, error) { func (g getCcInfoType) ParseResult(rawString string) (CcInfo, error) {
const expectedLen = 10 var ccInfo CcInfo
splitString := strings.Split(rawString, "|") decoder := json.NewDecoder(strings.NewReader(rawString))
if len(splitString) != expectedLen { decoder.DisallowUnknownFields() //useful to detect typos, e.g. in unit tests
return CcInfo{}, fmt.Errorf("expected %d items, got %q", expectedLen, splitString) err := decoder.Decode(&ccInfo)
} return ccInfo, err
outputFilesString := splitString[0]
ccObjectsString := splitString[1]
ccSharedLibrariesString := splitString[2]
ccStaticLibrariesString := splitString[3]
includesString := splitString[4]
systemIncludesString := splitString[5]
headersString := splitString[6]
rootStaticArchivesString := splitString[7]
rootDynamicLibrariesString := splitString[8]
tocFile := splitString[9] // NOTE: Will be the empty string if there wasn't
outputFiles := splitOrEmpty(outputFilesString, ", ")
ccObjects := splitOrEmpty(ccObjectsString, ", ")
ccSharedLibraries := splitOrEmpty(ccSharedLibrariesString, ", ")
ccStaticLibraries := splitOrEmpty(ccStaticLibrariesString, ", ")
includes := splitOrEmpty(includesString, ", ")
systemIncludes := splitOrEmpty(systemIncludesString, ", ")
headers := splitOrEmpty(headersString, ", ")
rootStaticArchives := splitOrEmpty(rootStaticArchivesString, ", ")
rootDynamicLibraries := splitOrEmpty(rootDynamicLibrariesString, ", ")
return CcInfo{
OutputFiles: outputFiles,
CcObjectFiles: ccObjects,
CcSharedLibraryFiles: ccSharedLibraries,
CcStaticLibraryFiles: ccStaticLibraries,
Includes: includes,
SystemIncludes: systemIncludes,
Headers: headers,
RootStaticArchives: rootStaticArchives,
RootDynamicLibraries: rootDynamicLibraries,
TocFile: tocFile,
}, nil
} }
// Query Bazel for the artifacts generated by the apex modules. // Query Bazel for the artifacts generated by the apex modules.

View File

@@ -1,9 +1,8 @@
package cquery package cquery
import ( import (
"fmt" "encoding/json"
"reflect" "reflect"
"strings"
"testing" "testing"
) )
@@ -63,74 +62,48 @@ func TestGetPythonBinaryParseResults(t *testing.T) {
} }
func TestGetCcInfoParseResults(t *testing.T) { func TestGetCcInfoParseResults(t *testing.T) {
const expectedSplits = 10
noResult := strings.Repeat("|", expectedSplits-1)
testCases := []struct { testCases := []struct {
description string description string
input string inputCcInfo CcInfo
expectedOutput CcInfo expectedOutput CcInfo
expectedErrorMessage string
}{ }{
{ {
description: "no result", description: "no result",
input: noResult, inputCcInfo: CcInfo{},
expectedOutput: CcInfo{ expectedOutput: CcInfo{},
OutputFiles: []string{},
CcObjectFiles: []string{},
CcSharedLibraryFiles: []string{},
CcStaticLibraryFiles: []string{},
Includes: []string{},
SystemIncludes: []string{},
Headers: []string{},
RootStaticArchives: []string{},
RootDynamicLibraries: []string{},
TocFile: "",
},
}, },
{ {
description: "only output", description: "only output",
input: "test" + noResult, inputCcInfo: CcInfo{
OutputFiles: []string{"test", "test3"},
},
expectedOutput: CcInfo{ expectedOutput: CcInfo{
OutputFiles: []string{"test"}, OutputFiles: []string{"test", "test3"},
CcObjectFiles: []string{},
CcSharedLibraryFiles: []string{},
CcStaticLibraryFiles: []string{},
Includes: []string{},
SystemIncludes: []string{},
Headers: []string{},
RootStaticArchives: []string{},
RootDynamicLibraries: []string{},
TocFile: "",
}, },
}, },
{ {
description: "only ToC", description: "only ToC",
input: noResult + "test", inputCcInfo: CcInfo{
TocFile: "test",
},
expectedOutput: CcInfo{ expectedOutput: CcInfo{
OutputFiles: []string{},
CcObjectFiles: []string{},
CcSharedLibraryFiles: []string{},
CcStaticLibraryFiles: []string{},
Includes: []string{},
SystemIncludes: []string{},
Headers: []string{},
RootStaticArchives: []string{},
RootDynamicLibraries: []string{},
TocFile: "test", TocFile: "test",
}, },
}, },
{ {
description: "all items set", description: "all items set",
input: "out1, out2" + inputCcInfo: CcInfo{
"|object1, object2" + OutputFiles: []string{"out1", "out2"},
"|shared_lib1, shared_lib2" + CcObjectFiles: []string{"object1", "object2"},
"|static_lib1, static_lib2" + CcSharedLibraryFiles: []string{"shared_lib1", "shared_lib2"},
"|., dir/subdir" + CcStaticLibraryFiles: []string{"static_lib1", "static_lib2"},
"|system/dir, system/other/dir" + Includes: []string{".", "dir/subdir"},
"|dir/subdir/hdr.h" + SystemIncludes: []string{"system/dir", "system/other/dir"},
"|rootstaticarchive1" + Headers: []string{"dir/subdir/hdr.h"},
"|rootdynamiclibrary1" + RootStaticArchives: []string{"rootstaticarchive1"},
"|lib.so.toc", RootDynamicLibraries: []string{"rootdynamiclibrary1"},
TocFile: "lib.so.toc",
},
expectedOutput: CcInfo{ expectedOutput: CcInfo{
OutputFiles: []string{"out1", "out2"}, OutputFiles: []string{"out1", "out2"},
CcObjectFiles: []string{"object1", "object2"}, CcObjectFiles: []string{"object1", "object2"},
@@ -144,24 +117,12 @@ func TestGetCcInfoParseResults(t *testing.T) {
TocFile: "lib.so.toc", TocFile: "lib.so.toc",
}, },
}, },
{
description: "too few result splits",
input: "|",
expectedOutput: CcInfo{},
expectedErrorMessage: fmt.Sprintf("expected %d items, got %q", expectedSplits, []string{"", ""}),
},
{
description: "too many result splits",
input: strings.Repeat("|", expectedSplits+1), // 2 too many
expectedOutput: CcInfo{},
expectedErrorMessage: fmt.Sprintf("expected %d items, got %q", expectedSplits, make([]string, expectedSplits+2)),
},
} }
for _, tc := range testCases { for _, tc := range testCases {
actualOutput, err := GetCcInfo.ParseResult(tc.input) jsonInput, _ := json.Marshal(tc.inputCcInfo)
if (err == nil && tc.expectedErrorMessage != "") || actualOutput, err := GetCcInfo.ParseResult(string(jsonInput))
(err != nil && err.Error() != tc.expectedErrorMessage) { if err != nil {
t.Errorf("%q:\n%12s: %q\n%12s: %q", tc.description, "expect Error", tc.expectedErrorMessage, "but got", err) t.Errorf("%q:\n test case get error: %q", tc.description, err)
} else if err == nil && !reflect.DeepEqual(tc.expectedOutput, actualOutput) { } else if err == nil && !reflect.DeepEqual(tc.expectedOutput, actualOutput) {
t.Errorf("%q:\n expected %#v\n!= actual %#v", tc.description, tc.expectedOutput, actualOutput) t.Errorf("%q:\n expected %#v\n!= actual %#v", tc.description, tc.expectedOutput, actualOutput)
} }