1package android
2
3import (
4	"os"
5	"path/filepath"
6	"reflect"
7	"testing"
8)
9
10func TestRequestResultsAfterInvokeBazel(t *testing.T) {
11	label := "//foo:bar"
12	arch := Arm64
13	bazelContext, _ := testBazelContext(t, map[bazelCommand]string{
14		bazelCommand{command: "cquery", expression: "kind(rule, deps(@soong_injection//mixed_builds:buildroot))"}: `//foo:bar|arm64>>out/foo/bar.txt`,
15	})
16	g, ok := bazelContext.GetOutputFiles(label, arch)
17	if ok {
18		t.Errorf("Did not expect cquery results prior to running InvokeBazel(), but got %s", g)
19	}
20	err := bazelContext.InvokeBazel()
21	if err != nil {
22		t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
23	}
24	g, ok = bazelContext.GetOutputFiles(label, arch)
25	if !ok {
26		t.Errorf("Expected cquery results after running InvokeBazel(), but got none")
27	} else if w := []string{"out/foo/bar.txt"}; !reflect.DeepEqual(w, g) {
28		t.Errorf("Expected output %s, got %s", w, g)
29	}
30}
31
32func TestInvokeBazelWritesBazelFiles(t *testing.T) {
33	bazelContext, baseDir := testBazelContext(t, map[bazelCommand]string{})
34	err := bazelContext.InvokeBazel()
35	if err != nil {
36		t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
37	}
38	if _, err := os.Stat(filepath.Join(baseDir, "soong_injection", "mixed_builds", "main.bzl")); os.IsNotExist(err) {
39		t.Errorf("Expected main.bzl to exist, but it does not")
40	} else if err != nil {
41		t.Errorf("Unexpected error stating main.bzl %s", err)
42	}
43
44	if _, err := os.Stat(filepath.Join(baseDir, "soong_injection", "mixed_builds", "BUILD.bazel")); os.IsNotExist(err) {
45		t.Errorf("Expected BUILD.bazel to exist, but it does not")
46	} else if err != nil {
47		t.Errorf("Unexpected error stating BUILD.bazel %s", err)
48	}
49
50	if _, err := os.Stat(filepath.Join(baseDir, "soong_injection", "WORKSPACE.bazel")); os.IsNotExist(err) {
51		t.Errorf("Expected WORKSPACE.bazel to exist, but it does not")
52	} else if err != nil {
53		t.Errorf("Unexpected error stating WORKSPACE.bazel %s", err)
54	}
55}
56
57func TestInvokeBazelPopulatesBuildStatements(t *testing.T) {
58	bazelContext, _ := testBazelContext(t, map[bazelCommand]string{
59		bazelCommand{command: "aquery", expression: "deps(@soong_injection//mixed_builds:buildroot)"}: `
60{
61  "artifacts": [{
62    "id": 1,
63    "pathFragmentId": 1
64  }, {
65    "id": 2,
66    "pathFragmentId": 2
67  }],
68  "actions": [{
69    "targetId": 1,
70    "actionKey": "x",
71    "mnemonic": "x",
72    "arguments": ["touch", "foo"],
73    "inputDepSetIds": [1],
74    "outputIds": [1],
75    "primaryOutputId": 1
76  }],
77  "depSetOfFiles": [{
78    "id": 1,
79    "directArtifactIds": [1, 2]
80  }],
81  "pathFragments": [{
82    "id": 1,
83    "label": "one"
84  }, {
85    "id": 2,
86    "label": "two"
87  }]
88}`,
89	})
90	err := bazelContext.InvokeBazel()
91	if err != nil {
92		t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
93	}
94
95	got := bazelContext.BuildStatementsToRegister()
96	if want := 1; len(got) != want {
97		t.Errorf("Expected %d registered build statements, got %#v", want, got)
98	}
99}
100
101func testBazelContext(t *testing.T, bazelCommandResults map[bazelCommand]string) (*bazelContext, string) {
102	t.Helper()
103	p := bazelPaths{
104		buildDir:     t.TempDir(),
105		outputBase:   "outputbase",
106		workspaceDir: "workspace_dir",
107	}
108	aqueryCommand := bazelCommand{command: "aquery", expression: "deps(@soong_injection//mixed_builds:buildroot)"}
109	if _, exists := bazelCommandResults[aqueryCommand]; !exists {
110		bazelCommandResults[aqueryCommand] = "{}\n"
111	}
112	runner := &mockBazelRunner{bazelCommandResults: bazelCommandResults}
113	return &bazelContext{
114		bazelRunner: runner,
115		paths:       &p,
116		requests:    map[cqueryKey]bool{},
117	}, p.buildDir
118}
119