265 lines
6.6 KiB
Go
265 lines
6.6 KiB
Go
// Copyright 2022 Google LLC
|
|
//
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
package exporter
|
|
|
|
import (
|
|
"bytes"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/mock"
|
|
"github.com/stretchr/testify/require"
|
|
"go.skia.org/infra/go/skerr"
|
|
"go.skia.org/skia/bazel/exporter/build_proto/analysis_v2"
|
|
"go.skia.org/skia/bazel/exporter/interfaces/mocks"
|
|
"google.golang.org/protobuf/encoding/prototext"
|
|
)
|
|
|
|
const testWorkspaceDir = "/path/to/workspace"
|
|
const testCMakeOutFname = "/not/necessarily/in/workspace/CMakeLists.txt"
|
|
|
|
// This input test data (in textproto format) started as output of
|
|
// a bazel cquery call - like:
|
|
//
|
|
// bazel cquery --noimplicit_deps 'kind("rule", deps(//:skia_public))' --output textproto
|
|
//
|
|
// and then hand edited to create a small valid query result with specific
|
|
// files, copts, and other cc_library/cc_binary rule attributes.
|
|
const textProto = `results {
|
|
target {
|
|
type: RULE
|
|
rule {
|
|
name: "//src/libs:sum"
|
|
rule_class: "cc_library"
|
|
location: "/path/to/workspace/src/libs/BUILD.bazel:8:11"
|
|
attribute {
|
|
name: "copts"
|
|
type: STRING_LIST
|
|
string_list_value: "-O2"
|
|
explicitly_specified: true
|
|
nodep: false
|
|
}
|
|
attribute {
|
|
name: "defines"
|
|
type: STRING_LIST
|
|
string_list_value: "SUMDEF"
|
|
explicitly_specified: false
|
|
nodep: false
|
|
}
|
|
attribute {
|
|
name: "includes"
|
|
type: STRING_LIST
|
|
string_list_value: "."
|
|
explicitly_specified: false
|
|
nodep: false
|
|
}
|
|
attribute {
|
|
name: "linkopts"
|
|
type: STRING_LIST
|
|
string_list_value: "-L/library/dir"
|
|
explicitly_specified: false
|
|
nodep: false
|
|
}
|
|
attribute {
|
|
name: "name"
|
|
type: STRING
|
|
string_value: "sum"
|
|
explicitly_specified: true
|
|
nodep: false
|
|
}
|
|
attribute {
|
|
name: "srcs"
|
|
type: LABEL_LIST
|
|
string_list_value: "//src/libs:sum.cpp"
|
|
explicitly_specified: true
|
|
nodep: false
|
|
}
|
|
attribute {
|
|
name: "hdrs"
|
|
type: LABEL_LIST
|
|
string_list_value: "//src/libs:sum.h"
|
|
explicitly_specified: true
|
|
nodep: false
|
|
}
|
|
attribute {
|
|
name: "visibility"
|
|
type: STRING_LIST
|
|
string_list_value: "//visibility:public"
|
|
explicitly_specified: true
|
|
nodep: true
|
|
}
|
|
}
|
|
},
|
|
}
|
|
results {
|
|
target {
|
|
type: RULE
|
|
rule {
|
|
name: "//src/apps:hello"
|
|
rule_class: "cc_binary"
|
|
location: "/path/to/workspace/src/apps/BUILD.bazel:8:11"
|
|
attribute {
|
|
name: "copts"
|
|
type: STRING_LIST
|
|
string_list_value: "-O1"
|
|
explicitly_specified: true
|
|
nodep: false
|
|
}
|
|
attribute {
|
|
name: "defines"
|
|
type: STRING_LIST
|
|
string_list_value: "APPDEF"
|
|
explicitly_specified: false
|
|
nodep: false
|
|
}
|
|
attribute {
|
|
name: "linkopts"
|
|
type: STRING_LIST
|
|
string_list_value: "-L/app/dir"
|
|
explicitly_specified: false
|
|
nodep: false
|
|
}
|
|
attribute {
|
|
name: "name"
|
|
type: STRING
|
|
string_value: "hello"
|
|
explicitly_specified: true
|
|
nodep: false
|
|
}
|
|
attribute {
|
|
name: "srcs"
|
|
type: LABEL_LIST
|
|
string_list_value: "//src/apps:hello-world.cpp"
|
|
explicitly_specified: true
|
|
nodep: false
|
|
}
|
|
attribute {
|
|
name: "deps"
|
|
type: LABEL_LIST
|
|
string_list_value: "//src/libs:sum"
|
|
explicitly_specified: false
|
|
nodep: false
|
|
}
|
|
attribute {
|
|
name: "visibility"
|
|
type: STRING_LIST
|
|
string_list_value: "//visibility:public"
|
|
explicitly_specified: true
|
|
nodep: true
|
|
}
|
|
}
|
|
}
|
|
}`
|
|
|
|
func TestExport_QueryReadError_ReturnsError(t *testing.T) {
|
|
fs := mocks.NewFileSystem(t)
|
|
e := NewCMakeExporter("projName", testWorkspaceDir, testCMakeOutFname, fs)
|
|
qcmd := mocks.NewQueryCommand(t)
|
|
qcmd.On("Read", mock.Anything).Return([]byte{}, skerr.Fmt("expected error"))
|
|
err := e.Export(qcmd)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestExport_InvalidProtobuf_ReturnsError(t *testing.T) {
|
|
fs := mocks.NewFileSystem(t)
|
|
e := NewCMakeExporter("projName", testWorkspaceDir, testCMakeOutFname, fs)
|
|
qcmd := mocks.NewQueryCommand(t)
|
|
qcmd.On("Read", mock.Anything).Return(make([]byte, 50), skerr.Fmt("empty data"))
|
|
err := e.Export(qcmd)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestExport_ValidProtobuf_Success(t *testing.T) {
|
|
protoData, err := textProtoToProtobuf(textProto)
|
|
require.NoError(t, err)
|
|
|
|
var contents bytes.Buffer
|
|
fs := mocks.NewFileSystem(t)
|
|
fs.On("OpenFile", mock.Anything).Once().Run(func(args mock.Arguments) {
|
|
assert.True(t, filepath.IsAbs(args.String(0)))
|
|
assert.Equal(t, args.String(0), testCMakeOutFname)
|
|
}).Return(&contents, nil)
|
|
e := NewCMakeExporter("projName", testWorkspaceDir, testCMakeOutFname, fs)
|
|
qcmd := mocks.NewQueryCommand(t)
|
|
qcmd.On("Read", mock.Anything).Return(protoData, nil)
|
|
err = e.Export(qcmd)
|
|
require.NoError(t, err)
|
|
|
|
// This expected CMake output text is created by hand.
|
|
const expected = `# DO NOT EDIT: This file is auto-generated.
|
|
cmake_minimum_required(VERSION 3.13)
|
|
|
|
project(projName LANGUAGES C CXX)
|
|
|
|
set(DEFAULT_COMPILE_FLAGS_MACOS "-std=c++17 -Wno-psabi --target=arm64-apple-macos11")
|
|
set(DEFAULT_COMPILE_FLAGS_LINUX "-std=c++17 -Wno-psabi -Wno-attributes")
|
|
|
|
if (APPLE)
|
|
set(DEFAULT_COMPILE_FLAGS "${DEFAULT_COMPILE_FLAGS_MACOS}")
|
|
else()
|
|
set(DEFAULT_COMPILE_FLAGS "${DEFAULT_COMPILE_FLAGS_LINUX}")
|
|
endif()
|
|
|
|
|
|
# //src/libs:sum
|
|
add_library(src_libs_sum "")
|
|
target_sources(src_libs_sum
|
|
PRIVATE
|
|
# Sources:
|
|
"${CMAKE_SOURCE_DIR}/src/libs/sum.cpp"
|
|
# Headers:
|
|
"${CMAKE_SOURCE_DIR}/src/libs/sum.h"
|
|
)
|
|
set_target_properties(src_libs_sum PROPERTIES COMPILE_FLAGS
|
|
"${DEFAULT_COMPILE_FLAGS} -O2"
|
|
)
|
|
set_target_properties(src_libs_sum PROPERTIES LINK_FLAGS
|
|
"-L/library/dir"
|
|
)
|
|
set_target_properties(src_libs_sum PROPERTIES COMPILE_DEFINITIONS
|
|
"SUMDEF"
|
|
)
|
|
set_target_properties(src_libs_sum PROPERTIES INCLUDE_DIRECTORIES
|
|
"${CMAKE_SOURCE_DIR}/src/libs;${CMAKE_SOURCE_DIR}"
|
|
)
|
|
|
|
# //src/apps:hello
|
|
add_executable(src_apps_hello "")
|
|
target_sources(src_apps_hello
|
|
PRIVATE
|
|
# Sources:
|
|
"${CMAKE_SOURCE_DIR}/src/apps/hello-world.cpp"
|
|
)
|
|
set_target_properties(src_apps_hello PROPERTIES COMPILE_FLAGS
|
|
"${DEFAULT_COMPILE_FLAGS} -O1"
|
|
)
|
|
set_target_properties(src_apps_hello PROPERTIES LINK_FLAGS
|
|
"-L/app/dir"
|
|
)
|
|
set_target_properties(src_apps_hello PROPERTIES COMPILE_DEFINITIONS
|
|
"APPDEF;SUMDEF"
|
|
)
|
|
set_target_properties(src_apps_hello PROPERTIES INCLUDE_DIRECTORIES
|
|
"${CMAKE_SOURCE_DIR}/src/libs;${CMAKE_SOURCE_DIR}"
|
|
)
|
|
`
|
|
assert.Equal(t, expected, contents.String())
|
|
}
|
|
|
|
func TestGetRuleCopts_CoptsExists_Success(t *testing.T) {
|
|
qr := analysis_v2.CqueryResult{}
|
|
err := prototext.Unmarshal([]byte(textProto), &qr)
|
|
require.NoError(t, err)
|
|
|
|
r := findRule(&qr, "//src/apps:hello")
|
|
require.NotNil(t, r)
|
|
|
|
copts, err := getRuleCopts(r)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, []string{"${DEFAULT_COMPILE_FLAGS}", "-O1"}, copts)
|
|
}
|