blob: adf48ab59399b6852cf7b5b5820d474a3b80304a [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package goldentest
import (
"context"
"flag"
"github.com/google/go-cmp/cmp"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
)
var (
testgen = flag.String("testgen", "", "Path to autotest binary")
cm = flag.String("cm", "", "Path to cm file")
golden = flag.String("golden", "", "Path to golden file directory for rust")
language = flag.String("language", "", "Accepts 'cpp' or 'rust'")
mock = flag.Bool("mock", false, "Whether to generate mocks")
output string
)
func setUp(t *testing.T) {
if _, err := os.Stat(*testgen); os.IsNotExist(err) {
t.Fatalf("Invalid testgen path %q err: %s", *testgen, err)
}
if _, err := os.Stat(*cm); os.IsNotExist(err) {
t.Fatalf("Invalid cm path %q err: %s", *cm, err)
}
if _, err := os.Stat(*golden); os.IsNotExist(err) {
t.Fatalf("Invalid golden path %q err: %s", *golden, err)
}
if *language != "rust" && *language != "cpp" {
t.Fatalf("Incorrect language %q allowed values are 'cpp' or 'rust'", *language)
}
}
func runTestGen(t *testing.T) {
testgen_abs, err := filepath.Abs(*testgen)
if err != nil {
t.Fatalf("Cannot find absolute path to testgen binary %s, error: %v", *testgen, err)
}
cm_abs, err := filepath.Abs(*cm)
if err != nil {
t.Fatalf("Cannot find absolute path to cm %s, error: %v", *cm, err)
}
td := t.TempDir()
output = filepath.Join(td, t.Name())
t.Logf("output %s", output)
args := []string{
"--cm-location", cm_abs, "--out-dir", output,
}
if *language == "cpp" {
args = append(args, "--cpp")
}
if *mock {
args = append(args, "--generate-mocks")
}
cmd := exec.CommandContext(
context.Background(),
testgen_abs,
args...,
)
cmd.Dir = td
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
t.Fatal(err)
}
}
func compareLineByLine(t *testing.T, golden, generated []string, filename string) {
if len(golden) != len(generated) {
t.Errorf("Found mismatched line count for %s: golden file contains %d lines and generateed file contains %d lines", filename, len(golden), len(generated))
}
for i, ref := range golden {
if diff := cmp.Diff(ref, generated[i]); diff != "" {
t.Errorf("Found mismatch in %s (-want +got):\n%s", filename, diff)
}
}
}
func compareGolden(t *testing.T) {
t.Logf("generated_build %s", output)
t.Logf("golden_build %s", *golden)
golden_abs, err := filepath.Abs(*golden)
if err != nil {
t.Fatalf("Cannot find absolute path to golden %s, error: %v", *golden, err)
}
// Build
generated_build, err := os.ReadFile(filepath.Join(output, "BUILD.gn"))
if err != nil {
t.Fatal(err)
}
golden_build, err := os.ReadFile(filepath.Join(golden_abs, "BUILD.gn.golden"))
if err != nil {
t.Fatal(err)
}
// Skip the first line that contains the copyright year.
compareLineByLine(t, strings.Split(string(golden_build), "\n")[1:], strings.Split(string(generated_build), "\n")[1:], "BUILD.gn")
// Manifest
generated_manifest, err := os.ReadFile(filepath.Join(output, "meta/echo_server_test.cml"))
if err != nil {
t.Fatal(err)
}
golden_manifest, err := os.ReadFile(filepath.Join(golden_abs, "echo_server_test.cml.golden"))
if err != nil {
t.Fatal(err)
}
// Skip the first line that contains the copyright year.
compareLineByLine(t, strings.Split(string(golden_manifest), "\n")[1:], strings.Split(string(generated_manifest), "\n")[1:], "manifest")
// Code
if *language == "rust" {
generated_code, err := os.ReadFile(filepath.Join(output, "src/echo_server_test.rs"))
if err != nil {
t.Fatal(err)
}
golden_code, err := os.ReadFile(filepath.Join(golden_abs, "echo_server_test.rs.golden"))
if err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(golden_code, generated_code); diff != "" {
t.Errorf("Found mismatch in generated rust code (-want +got):\n%s", diff)
}
}
if *language == "cpp" {
generated_code, err := os.ReadFile(filepath.Join(output, "src/echo_server_test.cc"))
if err != nil {
t.Fatal(err)
}
golden_code, err := os.ReadFile(filepath.Join(golden_abs, "echo_server_test.cc.golden"))
if err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(golden_code, generated_code); diff != "" {
t.Errorf("Found mismatch in generated cpp code (-want +got):\n%s", diff)
}
}
}
func Test_Golden(t *testing.T) {
setUp(t)
runTestGen(t)
compareGolden(t)
}