// Copyright 2018 The Goma 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 remoteexec

import (
	"bytes"
	"context"
	"fmt"
	"path/filepath"
	"reflect"
	"sort"
	"testing"
	"time"

	rpb "github.com/bazelbuild/remote-apis/build/bazel/remote/execution/v2"
	"github.com/golang/protobuf/proto"
	"github.com/google/go-cmp/cmp"
	bpb "google.golang.org/genproto/googleapis/bytestream"

	gomapb "go.chromium.org/goma/server/proto/api"
	cachepb "go.chromium.org/goma/server/proto/cache"
	cmdpb "go.chromium.org/goma/server/proto/command"
	fpb "go.chromium.org/goma/server/proto/file"
	"go.chromium.org/goma/server/remoteexec/cas"
	"go.chromium.org/goma/server/remoteexec/digest"
)

func TestAdapterHandleMissingCompiler(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	cluster := &fakeCluster{
		rbe: newFakeRBE(),
	}
	err := cluster.setup(ctx, cluster.rbe.instancePrefix)
	if err != nil {
		t.Fatal(err)
	}
	defer cluster.teardown()

	clangUnknown := newFakeClang(&cluster.cmdStorage, "1111", "x86-64-linux-gnu")
	clang := newFakeClang(&cluster.cmdStorage, "1234", "x86-64-linux-gnu")

	err = cluster.pushToolchains(ctx, clang)
	if err != nil {
		t.Fatal(err)
	}

	var localFiles fakeLocalFiles
	localFiles.Add("/b/c/w/src/hello.cc", randomSize())
	localFiles.Add("/b/c/w/include/hello.h", randomSize())

	req := &gomapb.ExecReq{
		// client requests with unknown clang for goma.
		CommandSpec: clangUnknown.CommandSpec("clang", "bin/clang"),
		Arg: []string{
			"bin/clang", "-I../../include",
			"-c", "../../src/hello.cc",
		},
		Env: []string{},
		Cwd: proto.String("/b/c/w/out/Release"),
		Input: []*gomapb.ExecReq_Input{
			localFiles.mustInput(ctx, t, nil, "/b/c/w/src/hello.cc", "../../src/hello.cc"),
			localFiles.mustInput(ctx, t, nil, "/b/c/w/include/hello.h", "../../include/hello.h"),
		},
		Subprogram:    []*gomapb.SubprogramSpec{},
		RequesterInfo: &gomapb.RequesterInfo{},
		HermeticMode:  proto.Bool(true),
	}

	resp, err := cluster.adapter.Exec(ctx, req)
	if err != nil {
		t.Fatalf("Exec(ctx, req)=%v; %v; want nil error", resp, err)
	}

	if resp.GetError() != gomapb.ExecResp_BAD_REQUEST {
		t.Errorf("Exec error=%v; want=%v", resp.GetError(), gomapb.ExecResp_BAD_REQUEST)
	}
	// client CompileTask::CheckNoMatchingCommandSpec
	if resp.GetResult().CommandSpec == nil {
		t.Errorf("Exec missing command_spec")
	}
	commandSpec := resp.GetResult().GetCommandSpec()
	if commandSpec.BinaryHash != nil {
		t.Errorf("Exec command_spec.binary_hash=%q; want not set",
			string(commandSpec.BinaryHash))
	}
}

func handleMissingInputs(ctx context.Context, t *testing.T, gomaFile fpb.FileServiceClient, localFiles fakeLocalFiles, req *gomapb.ExecReq, resp *gomapb.ExecResp) {
	t.Logf("client uploads/embeds missing inputs")
	if resp.GetError() != gomapb.ExecResp_OK {
		t.Errorf("Exec error=%v; want=%v", resp.GetError(), gomapb.ExecResp_OK)
	}
Loop:
	for i, input := range req.Input {
		for _, fname := range resp.MissingInput {
			if input.GetFilename() == fname {
				fullname := filepath.Join(req.GetCwd(), fname)
				t.Logf("upload/embed %s", fullname)
				req.Input[i] = localFiles.mustInput(ctx, t, gomaFile, fullname, fname)
				continue Loop
			}
		}
	}
}

func TestAdapterHandleMissingInput(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	cluster := &fakeCluster{
		rbe: newFakeRBE(),
	}
	err := cluster.setup(ctx, cluster.rbe.instancePrefix)
	if err != nil {
		t.Fatal(err)
	}
	defer cluster.teardown()

	clang := newFakeClang(&cluster.cmdStorage, "1234", "x86-64-linux-gnu")

	err = cluster.pushToolchains(ctx, clang)
	if err != nil {
		t.Fatal(err)
	}

	var localFiles fakeLocalFiles
	localFiles.Add("/b/c/w/src/hello.cc", randomSize())
	localFiles.Add("/b/c/w/include/hello.h", randomSize())

	req := &gomapb.ExecReq{
		CommandSpec: clang.CommandSpec("clang", "bin/clang"),
		Arg: []string{
			"bin/clang", "-I../../include",
			"-c", "../../src/hello.cc",
		},
		Env: []string{},
		Cwd: proto.String("/b/c/w/out/Release"),
		Input: []*gomapb.ExecReq_Input{
			// client sends hash only (fc==nil).
			localFiles.mustInput(ctx, t, nil, "/b/c/w/src/hello.cc", "../../src/hello.cc"),
			localFiles.mustInput(ctx, t, nil, "/b/c/w/include/hello.h", "../../include/hello.h"),
		},
		Subprogram:    []*gomapb.SubprogramSpec{},
		RequesterInfo: &gomapb.RequesterInfo{},
		HermeticMode:  proto.Bool(true),
	}

	t.Logf("first call")
	resp, err := cluster.adapter.Exec(ctx, req)
	if err != nil {
		t.Fatalf("Exec(ctx, req)=%v; %v; want nil error", resp, err)
	}
	if resp.GetError() != gomapb.ExecResp_OK {
		t.Errorf("Exec error=%v; want=%v", resp.GetError(), gomapb.ExecResp_OK)
	}

	wantMissing := []string{"../../src/hello.cc", "../../include/hello.h"}

	if !reflect.DeepEqual(resp.MissingInput, wantMissing) {
		t.Fatalf("missing=%q; want=%q", resp.MissingInput, wantMissing)
	}
	if len(resp.MissingInput) != len(resp.MissingReason) {
		t.Fatalf("missing: len(input)=%d != len(reason)=%d", len(resp.MissingInput), len(resp.MissingReason))
	}

	handleMissingInputs(ctx, t, cluster.adapter.GomaFile, localFiles, req, resp)

	t.Logf("second call")
	resp, err = cluster.adapter.Exec(ctx, req)
	if err != nil {
		t.Fatalf("Exec(ctx, req)=%v; %v; want nil error", resp, err)
	}
	if resp.GetError() != gomapb.ExecResp_OK {
		t.Errorf("Exec error=%v; want=%v", resp.GetError(), gomapb.ExecResp_OK)
	}
	if len(resp.MissingInput) > 0 {
		t.Fatalf("missing=%v; want no missing", resp.MissingInput)
	}
}

func TestAdapterHandleMissingInputFilename(t *testing.T) {
	// http://b/132391933 should not get filename from digest_cache.
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	cluster := &fakeCluster{
		rbe: newFakeRBE(),
	}
	err := cluster.setup(ctx, cluster.rbe.instancePrefix)
	if err != nil {
		t.Fatal(err)
	}
	defer cluster.teardown()

	clang := newFakeClang(&cluster.cmdStorage, "1234", "x86-64-linux-gnu")

	err = cluster.pushToolchains(ctx, clang)
	if err != nil {
		t.Fatal(err)
	}

	var localFiles fakeLocalFiles
	localFiles.Add("/b/c/w/src/hello.cc", randomSize())
	localFiles.Add("/b/c/w/include/hello.h", randomSize())

	req := &gomapb.ExecReq{
		CommandSpec: clang.CommandSpec("clang", "bin/clang"),
		Arg: []string{
			"bin/clang", "-I../../include",
			"-c", "../../src/hello.cc",
		},
		Env: []string{},
		Cwd: proto.String("/b/c/w/out/Release"),
		Input: []*gomapb.ExecReq_Input{
			localFiles.mustInput(ctx, t, cluster.adapter.GomaFile, "/b/c/w/src/hello.cc", "../../src/hello.cc"),
			localFiles.mustInput(ctx, t, cluster.adapter.GomaFile, "/b/c/w/include/hello.h", "../../include/hello.h"),
		},
		Subprogram:    []*gomapb.SubprogramSpec{},
		RequesterInfo: &gomapb.RequesterInfo{},
		HermeticMode:  proto.Bool(true),
	}

	t.Logf("first call")
	resp, err := cluster.adapter.Exec(ctx, req)
	if err != nil {
		t.Fatalf("Exec(ctx, req)=%v; %v; want nil error", resp, err)
	}
	if resp.GetError() != gomapb.ExecResp_OK {
		t.Errorf("Exec error=%v; want=%v", resp.GetError(), gomapb.ExecResp_OK)
	}
	if len(resp.MissingInput) > 0 {
		t.Fatalf("missing=%v; want no missing", resp.MissingInput)
	}

	t.Logf("clear in-memory digest cache, but still in redis.")
	cluster.adapter.DigestCache = digest.NewCache(&cluster.redis)

	req = &gomapb.ExecReq{
		CommandSpec: clang.CommandSpec("clang", "bin/clang"),
		Arg: []string{
			"bin/clang", "-I../../include",
			"-c", "../../src/hello.cc",
		},
		Env: []string{},
		Cwd: proto.String("/b/c/w/out/Release"),
		Input: []*gomapb.ExecReq_Input{
			localFiles.mustInput(ctx, t, nil, "/b/c/w/src/hello.cc", "../../src/hello.cc"),
			localFiles.mustInput(ctx, t, nil, "/b/c/w/include/hello.h", "../../include/hello.h"),
		},
		Subprogram:    []*gomapb.SubprogramSpec{},
		RequesterInfo: &gomapb.RequesterInfo{},
		HermeticMode:  proto.Bool(true),
	}
	t.Logf("second call, clear in-memory content in digest cache")
	resp, err = cluster.adapter.Exec(ctx, req)
	if err != nil {
		t.Fatalf("Exec(ctx, req)=%v; %v; want nil error", resp, err)
	}
	if resp.GetError() != gomapb.ExecResp_OK {
		t.Errorf("Exec error=%v; want=%v", resp.GetError(), gomapb.ExecResp_OK)
	}
	if len(resp.MissingInput) > 0 {
		t.Fatalf("missing=%v; want no missing", resp.MissingInput)
	}

	localFiles.Dup("/b/c/w/src/hello.cc", "/b/c/w/src/hello2.cc")
	localFiles.Dup("/b/c/w/include/hello.h", "/b/c/w/include/hello2.h")

	req = &gomapb.ExecReq{
		CommandSpec: clang.CommandSpec("clang", "bin/clang"),
		Arg: []string{
			"bin/clang", "-I../../include",
			"-c", "../../src/hello2.cc",
		},
		Env: []string{},
		Cwd: proto.String("/b/c/w/out/Release"),
		Input: []*gomapb.ExecReq_Input{
			// client sends hash only (fc==nil).
			localFiles.mustInput(ctx, t, nil, "/b/c/w/src/hello2.cc", "../../src/hello2.cc"),
			localFiles.mustInput(ctx, t, nil, "/b/c/w/include/hello2.h", "../../include/hello2.h"),
		},
		Subprogram:    []*gomapb.SubprogramSpec{},
		RequesterInfo: &gomapb.RequesterInfo{},
		HermeticMode:  proto.Bool(true),
	}
	t.Logf("reset cas and file-server cache")
	cluster.rbe.cas = digest.NewStore()
	for _, input := range req.Input {
		_, err = cluster.cache.Put(ctx, &cachepb.PutReq{
			Kv: &cachepb.KV{
				Key: input.GetHashKey(),
			},
		})
		if err != nil {
			t.Fatalf("reset cache %s: %v", input, err)
		}
	}

	t.Logf("third call, different filename")

	resp, err = cluster.adapter.Exec(ctx, req)
	if err != nil {
		t.Fatalf("Exec(ctx, req)=%v; %v; want nil error", resp, err)
	}
	if resp.GetError() != gomapb.ExecResp_OK {
		t.Errorf("Exec error=%v; want=%v", resp.GetError(), gomapb.ExecResp_OK)
	}

	wantMissing := []string{"../../src/hello2.cc", "../../include/hello2.h"}

	if !cmp.Equal(resp.MissingInput, wantMissing) {
		t.Fatalf("missing=%v; want=%v", resp.MissingInput, wantMissing)
	}
	if len(resp.MissingInput) != len(resp.MissingReason) {
		t.Fatalf("missing: len(input)=%d != len(reason)=%d", len(resp.MissingInput), len(resp.MissingReason))
	}
}

func TestAdapterHandleMissingInputContents(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	cluster := &fakeCluster{
		rbe: newFakeRBE(),
	}
	err := cluster.setup(ctx, cluster.rbe.instancePrefix)
	if err != nil {
		t.Fatal(err)
	}
	defer cluster.teardown()

	clang := newFakeClang(&cluster.cmdStorage, "1234", "x86-64-linux-gnu")

	err = cluster.pushToolchains(ctx, clang)
	if err != nil {
		t.Fatal(err)
	}

	var localFiles fakeLocalFiles
	localFiles.Add("/b/c/w/src/hello.cc", randomSize())
	localFiles.Add("/b/c/w/include/hello.h", randomSize())

	// these files exists in digest cache, but not in CAS yet.
	input := localFiles.mustInput(ctx, t, nil, "/b/c/w/src/hello.cc", "../../src/hello.cc")
	cluster.redis.mustSet(ctx, t, input.GetHashKey(), localFiles.mustDigest(ctx, t, "/b/c/w/src/hello.cc"))
	input = localFiles.mustInput(ctx, t, nil, "/b/c/w/include/hello.h", "../../include/hello.h")
	cluster.redis.mustSet(ctx, t, input.GetHashKey(), localFiles.mustDigest(ctx, t, "/b/c/w/include/hello.h"))

	req := &gomapb.ExecReq{
		CommandSpec: clang.CommandSpec("clang", "bin/clang"),
		Arg: []string{
			"bin/clang", "-I../../include",
			"-c", "../../src/hello.cc",
		},
		Env: []string{},
		Cwd: proto.String("/b/c/w/out/Release"),
		Input: []*gomapb.ExecReq_Input{
			// client sends hash only (fc==nil).
			localFiles.mustInput(ctx, t, nil, "/b/c/w/src/hello.cc", "../../src/hello.cc"),
			localFiles.mustInput(ctx, t, nil, "/b/c/w/include/hello.h", "../../include/hello.h"),
		},
		Subprogram:    []*gomapb.SubprogramSpec{},
		RequesterInfo: &gomapb.RequesterInfo{},
		HermeticMode:  proto.Bool(true),
	}

	t.Logf("first call")
	// found in digest in digest cache, but no content in CAS yet.
	// return missing input instead of internal error. http://b/123546251
	resp, err := cluster.adapter.Exec(ctx, req)
	if err != nil {
		t.Fatalf("Exec(ctx, req)=%v; %v; want nil error", resp, err)
	}
	if resp.GetError() != gomapb.ExecResp_OK {
		t.Errorf("Exec error=%v; want=%v", resp.GetError(), gomapb.ExecResp_OK)
	}

	wantMissing := []string{"../../src/hello.cc", "../../include/hello.h"}

	if !reflect.DeepEqual(resp.MissingInput, wantMissing) {
		t.Fatalf("missing=%q; want=%q", resp.MissingInput, wantMissing)
	}
	if len(resp.MissingInput) != len(resp.MissingReason) {
		t.Fatalf("missing: len(input)=%d != len(reason)=%d", len(resp.MissingInput), len(resp.MissingReason))
	}

	handleMissingInputs(ctx, t, cluster.adapter.GomaFile, localFiles, req, resp)

	t.Logf("second call")
	resp, err = cluster.adapter.Exec(ctx, req)
	if err != nil {
		t.Fatalf("Exec(ctx, req)=%v; %v; want nil error", resp, err)
	}
	if resp.GetError() != gomapb.ExecResp_OK {
		t.Errorf("Exec error=%v; want=%v", resp.GetError(), gomapb.ExecResp_OK)
	}
	if len(resp.MissingInput) > 0 {
		t.Fatalf("missing=%v; want no missing", resp.MissingInput)
	}
}

func TestAdapterHandleSameCwdAndInputRoot(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	cluster := &fakeCluster{
		rbe: newFakeRBE(),
	}
	err := cluster.setup(ctx, cluster.rbe.instancePrefix)
	if err != nil {
		t.Fatal(err)
	}
	defer cluster.teardown()

	clang := newFakeClang(&cluster.cmdStorage, "1234", "x86-64-linux-gnu")

	err = cluster.pushToolchains(ctx, clang)
	if err != nil {
		t.Fatal(err)
	}

	var localFiles fakeLocalFiles
	localFiles.Add("/cwd/hello.cc", randomSize())

	cs := clang.CommandSpec("clang", "clang")

	req := &gomapb.ExecReq{
		CommandSpec: cs,
		Arg: []string{
			"./clang", "-c", "./hello.cc",
		},
		Env: []string{},
		Cwd: proto.String("/cwd"),
		Input: []*gomapb.ExecReq_Input{
			localFiles.mustInput(ctx, t, cluster.adapter.GomaFile, "/cwd/hello.cc", "hello.cc"),
		},
		Subprogram:    []*gomapb.SubprogramSpec{},
		RequesterInfo: &gomapb.RequesterInfo{},
		HermeticMode:  proto.Bool(true),
	}

	resp, err := cluster.adapter.Exec(ctx, req)
	if err != nil {
		t.Fatalf("Exec(ctx, req)=%v; %v; want nil error", resp, err)
	}
	if resp.GetError() != gomapb.ExecResp_OK {
		t.Errorf("Exec error=%v; want=%v", resp.GetError(), gomapb.ExecResp_OK)
	}

	command := cluster.rbe.gotCommand
	if command == nil {
		t.Fatalf("gotCommand is nil")
	}
	if len(command.Arguments) == 0 {
		t.Errorf("arguments must not be empty")
	}

	firstArg := command.Arguments[0]
	if firstArg != "./run.sh" {
		t.Errorf(`command.Arguments[0]=%q; want="./run.sh"`, firstArg)
	}

	if command.WorkingDirectory != "" {
		t.Errorf(`command.WorkingDirectory=%q; want=""`, command.WorkingDirectory)
	}
	workDirExists := false
	for _, v := range command.EnvironmentVariables {
		if v.Name == "WORK_DIR" {
			workDirExists = true
			if v.Value != "." {
				t.Errorf(`WORK_DIR=%q; want="."`, v.Value)
			}
		}
	}

	if !workDirExists {
		t.Errorf("WORK_DIR not found")
	}
	// TODO: add test case that Command.WorkingDirectory is set.
}

func TestAdapterHandleOutputs(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	cluster := &fakeCluster{
		rbe: newFakeRBE(),
	}
	err := cluster.setup(ctx, cluster.rbe.instancePrefix)
	if err != nil {
		t.Fatal(err)
	}
	defer cluster.teardown()

	clang := newFakeClang(&cluster.cmdStorage, "1234", "x86-64-linux-gnu")

	err = cluster.pushToolchains(ctx, clang)
	if err != nil {
		t.Fatal(err)
	}

	var localFiles fakeLocalFiles
	localFiles.Add("/b/c/w/src/hello.cc", randomSize())
	localFiles.Add("/b/c/w/include/hello.h", randomSize())

	cs := clang.CommandSpec("clang", "bin/clang")

	req := &gomapb.ExecReq{
		CommandSpec: cs,
		Arg: []string{
			"bin/clang", "-I../../include",
			"-c", "../../src/hello.cc",
		},
		Env: []string{},
		Cwd: proto.String("/b/c/w/out/Release"),
		Input: []*gomapb.ExecReq_Input{
			localFiles.mustInput(ctx, t, cluster.adapter.GomaFile, "/b/c/w/src/hello.cc", "../../src/hello.cc"),
			localFiles.mustInput(ctx, t, cluster.adapter.GomaFile, "/b/c/w/include/hello.h", "../../include/hello.h"),
		},
		Subprogram:          []*gomapb.SubprogramSpec{},
		RequesterInfo:       &gomapb.RequesterInfo{},
		HermeticMode:        proto.Bool(true),
		ExpectedOutputFiles: []string{"hello.o"},
		ExpectedOutputDirs:  []string{"fake-directory"},
	}

	resp, err := cluster.adapter.Exec(ctx, req)
	if err != nil {
		t.Fatalf("Exec(ctx, req)=%v; %v; want nil error", resp, err)
	}
	if resp.GetError() != gomapb.ExecResp_OK {
		t.Errorf("Exec error=%v; want=%v", resp.GetError(), gomapb.ExecResp_OK)
	}

	command := cluster.rbe.gotCommand
	if command == nil {
		t.Fatalf("gotCommand is nil")
	}

	wantOutputFiles := []string{
		"out/Release/hello.o",
	}
	wantOutputDirs := []string{
		"out/Release/fake-directory",
	}

	if !reflect.DeepEqual(command.OutputFiles, wantOutputFiles) {
		t.Errorf("output files: got=%v, want=%v", command.OutputFiles, wantOutputFiles)
	}
	if !reflect.DeepEqual(command.OutputDirectories, wantOutputDirs) {
		t.Errorf("output dirs: got=%v, want=%v", command.OutputDirectories, wantOutputDirs)
	}
}

func TestAdapterHandleOutputsWithoutExpectedOutputs(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	cluster := &fakeCluster{
		rbe: newFakeRBE(),
	}
	err := cluster.setup(ctx, cluster.rbe.instancePrefix)
	if err != nil {
		t.Fatal(err)
	}
	defer cluster.teardown()

	clang := newFakeClang(&cluster.cmdStorage, "1234", "x86-64-linux-gnu")

	err = cluster.pushToolchains(ctx, clang)
	if err != nil {
		t.Fatal(err)
	}

	var localFiles fakeLocalFiles
	localFiles.Add("/b/c/w/src/hello.cc", randomSize())
	localFiles.Add("/b/c/w/include/hello.h", randomSize())

	cs := clang.CommandSpec("clang", "bin/clang")

	req := &gomapb.ExecReq{
		CommandSpec: cs,
		Arg: []string{
			"bin/clang", "-I../../include",
			"-c", "../../src/hello.cc",
			"-o", "hello.o",
		},
		Env: []string{},
		Cwd: proto.String("/b/c/w/out/Release"),
		Input: []*gomapb.ExecReq_Input{
			localFiles.mustInput(ctx, t, cluster.adapter.GomaFile, "/b/c/w/src/hello.cc", "../../src/hello.cc"),
			localFiles.mustInput(ctx, t, cluster.adapter.GomaFile, "/b/c/w/include/hello.h", "../../include/hello.h"),
		},
		Subprogram:    []*gomapb.SubprogramSpec{},
		RequesterInfo: &gomapb.RequesterInfo{},
		HermeticMode:  proto.Bool(true),
	}

	resp, err := cluster.adapter.Exec(ctx, req)
	if err != nil {
		t.Fatalf("Exec(ctx, req)=%v; %v; want nil error", resp, err)
	}
	if resp.GetError() != gomapb.ExecResp_OK {
		t.Errorf("Exec error=%v; want=%v", resp.GetError(), gomapb.ExecResp_OK)
	}

	command := cluster.rbe.gotCommand
	if command == nil {
		t.Fatalf("gotCommand is nil")
	}

	wantOutputFiles := []string{
		"out/Release/hello.o",
	}
	var wantOutputDirs []string

	if !reflect.DeepEqual(command.OutputFiles, wantOutputFiles) {
		t.Errorf("output files: got=%v, want=%v", command.OutputFiles, wantOutputFiles)
	}
	if !reflect.DeepEqual(command.OutputDirectories, wantOutputDirs) {
		t.Errorf("output dirs: got=%v, want=%v", command.OutputDirectories, wantOutputDirs)
	}
}

func TestAdapterHandleCrossCompile(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	cluster := &fakeCluster{
		rbe: newFakeRBE(),
	}
	err := cluster.setup(ctx, cluster.rbe.instancePrefix)
	if err != nil {
		t.Fatal(err)
	}
	defer cluster.teardown()

	clang := newFakeClang(&cluster.cmdStorage, "1234", "x86_64-darwin")
	for _, desc := range clang.descs {
		desc.Cross = &cmdpb.CmdDescriptor_Cross{
			ClangNeedTarget: true,
		}
	}

	err = cluster.pushToolchains(ctx, clang)
	if err != nil {
		t.Fatal(err)
	}

	var localFiles fakeLocalFiles
	localFiles.Add("/b/c/w/src/hello.cc", randomSize())
	localFiles.Add("/b/c/w/include/hello.h", randomSize())

	cs := clang.CommandSpec("clang", "bin/clang")
	cs.Target = proto.String("x86_64-apple-darwin10.6.0")

	req := &gomapb.ExecReq{
		CommandSpec: cs,
		Arg: []string{
			"bin/clang", "-I../../include",
			"-c", "../../src/hello.cc",
			"-o", "hello.o",
		},
		Env: []string{},
		Cwd: proto.String("/b/c/w/out/Release"),
		Input: []*gomapb.ExecReq_Input{
			localFiles.mustInput(ctx, t, cluster.adapter.GomaFile, "/b/c/w/src/hello.cc", "../../src/hello.cc"),
			localFiles.mustInput(ctx, t, cluster.adapter.GomaFile, "/b/c/w/include/hello.h", "../../include/hello.h"),
		},
		Subprogram:    []*gomapb.SubprogramSpec{},
		RequesterInfo: &gomapb.RequesterInfo{},
		HermeticMode:  proto.Bool(true),
	}

	resp, err := cluster.adapter.Exec(ctx, req)
	if err != nil {
		t.Fatalf("Exec(ctx, req)=%v; %v; want nil error", resp, err)
	}
	if resp.GetError() != gomapb.ExecResp_OK {
		t.Errorf("Exec error=%v; want=%v", resp.GetError(), gomapb.ExecResp_OK)
	}

	command := cluster.rbe.gotCommand
	if command == nil {
		t.Fatalf("gotCommand is nil")
	}

	wantArguments := []string{
		"out/Release/run.sh", "bin/clang", "-I../../include",
		"-c", "../../src/hello.cc",
		"-o", "hello.o",
		"--target=x86_64-apple-darwin10.6.0",
	}
	if !reflect.DeepEqual(command.Arguments, wantArguments) {
		t.Errorf("arguments: got=%q, want=%q", command.Arguments, wantArguments)
	}
}

type fileState struct {
	digest       *rpb.Digest
	isFile       bool
	isDir        bool
	isExecutable bool
}

// TODO: implement this with GetTree?
func dumpDirIter(ctx context.Context, t *testing.T, bs bpb.ByteStreamClient, instance, dir string, d *rpb.Digest, files map[string]fileState) error {
	t.Logf("dir:%s %s", dir, d)

	resname := cas.ResName(instance, d)
	var buf bytes.Buffer
	size, err := cas.Download(ctx, bs, &buf, resname)
	if err != nil {
		return fmt.Errorf("download dir:%s %s: %v", dir, d, err)
	}
	if size != d.SizeBytes {
		return fmt.Errorf("incomplete fetch %v: size=%d", d, size)
	}
	curdir := &rpb.Directory{}
	err = proto.Unmarshal(buf.Bytes(), curdir)
	if err != nil {
		return fmt.Errorf("unmarshal dir:%s %s: %v", dir, d, err)
	}
	for _, f := range curdir.Files {
		fname := filepath.Join(dir, f.Name)
		files[fname] = fileState{
			digest:       f.Digest,
			isFile:       true,
			isExecutable: f.IsExecutable,
		}
		t.Logf("file:%s %s x:%t", fname, f.Digest, f.IsExecutable)
	}
	for _, subdir := range curdir.Directories {
		dname := filepath.Join(dir, subdir.Name)
		files[dname] = fileState{
			isDir: true,
		}
		err := dumpDirIter(ctx, t, bs, instance, dname, subdir.Digest, files)
		if err != nil {
			return err
		}
	}
	return nil
}

// dumpDirs dumps file list and directory list.
// The value of `files` means a file is executable or not.
func dumpDir(ctx context.Context, t *testing.T, bs bpb.ByteStreamClient, instance, dir string, d *rpb.Digest) (map[string]fileState, error) {
	files := make(map[string]fileState)
	err := dumpDirIter(ctx, t, bs, instance, dir, d, files)
	if err != nil {
		return nil, err
	}
	return files, nil
}

func TestAdapterHandleOutputsWithSystemIncludePaths(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	cluster := &fakeCluster{
		rbe: newFakeRBE(),
	}
	err := cluster.setup(ctx, cluster.rbe.instancePrefix)
	if err != nil {
		t.Fatal(err)
	}
	defer cluster.teardown()

	clang := newFakeClang(&cluster.cmdStorage, "1234", "x86-64-linux-gnu")

	err = cluster.pushToolchains(ctx, clang)
	if err != nil {
		t.Fatal(err)
	}

	var localFiles fakeLocalFiles
	localFiles.Add("/b/c/w/src/hello.cc", randomSize())
	localFiles.Add("/b/c/w/include/hello.h", randomSize())

	cs := clang.CommandSpec("clang", "bin/clang")

	req := &gomapb.ExecReq{
		CommandSpec: cs,
		Arg: []string{
			"bin/clang", "-I../../include",
			"--sysroot=../../build/linux/debian_sid_amd64-sysroot",
			"-c", "../../src/hello.cc",
			"-o", "hello.o",
		},
		Env: []string{},
		Cwd: proto.String("/b/c/w/out/Release"),
		Input: []*gomapb.ExecReq_Input{
			localFiles.mustInput(ctx, t, cluster.adapter.GomaFile, "/b/c/w/src/hello.cc", "../../src/hello.cc"),
			localFiles.mustInput(ctx, t, cluster.adapter.GomaFile, "/b/c/w/include/hello.h", "../../include/hello.h"),
		},
		Subprogram:    []*gomapb.SubprogramSpec{},
		RequesterInfo: &gomapb.RequesterInfo{},
		HermeticMode:  proto.Bool(true),
	}
	req.CommandSpec.SystemIncludePath = []string{
		"../../build/linux/debian_sid_amd64-sysroot/usr/include/x86_64-linux-gnu",
	}

	resp, err := cluster.adapter.Exec(ctx, req)
	if err != nil {
		t.Fatalf("Exec(ctx, req)=%v; %v; want nil error", resp, err)
	}
	if resp.GetError() != gomapb.ExecResp_OK {
		t.Errorf("Exec error=%v; want=%v", resp.GetError(), gomapb.ExecResp_OK)
	}

	action := cluster.rbe.gotAction
	if action == nil {
		t.Fatalf("gotAction is nil")
	}
	files, err := dumpDir(ctx, t, cluster.adapter.Client, cluster.adapter.DefaultInstance(), ".", action.InputRootDigest)
	if err != nil {
		t.Fatalf("err %v", err)
	}
	if !files["build/linux/debian_sid_amd64-sysroot/usr/include/x86_64-linux-gnu"].isDir {
		t.Errorf("want CAS has build/linux/debian_sid_amd64-sysroot/usr/include/x86_64-linux-gnu; files=%v", files)
	}
}

func TestAdaptorHandleArbitraryToolchainSupport(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	cluster := &fakeCluster{
		rbe: newFakeRBE(),
	}
	err := cluster.setup(ctx, cluster.rbe.instancePrefix)
	if err != nil {
		t.Fatal(err)
	}
	defer cluster.teardown()

	// Instead of adding a new compiler, register toolchain platform.
	err = cluster.pushPlatform(ctx, "docker://grpc.io/goma-dev/container-image@sha256:yyyy", []string{"os:linux"})
	if err != nil {
		t.Fatal(err)
	}

	var localFiles fakeLocalFiles
	localFiles.Add("/b/c/w/bin/clang", randomBigSize())
	localFiles.Add("/b/c/w/include/hello.h", randomSize())
	localFiles.Add("/b/c/w/src/hello.c", randomSize())

	clangToolchainInput := localFiles.mustInput(ctx, t, cluster.adapter.GomaFile, "/b/c/w/bin/clang", "../../bin/clang")
	clangHashKey := localFiles.mustFileHash(ctx, t, "/b/c/w/bin/clang")

	req := &gomapb.ExecReq{
		CommandSpec: &gomapb.CommandSpec{
			Name:              proto.String("clang"),
			Version:           proto.String("1234"),
			Target:            proto.String("x86-64-linux-gnu"),
			BinaryHash:        []byte(clangHashKey),
			LocalCompilerPath: proto.String("../../bin/clang"),
		},
		Arg: []string{
			"../../bin/clang", "-Iinclude",
			"-c", "../../src/hello.c",
			"-o", "hello.o",
		},
		Env: []string{"PWD=/b/c/w/out/Release"},
		Cwd: proto.String("/b/c/w/out/Release"),
		Input: []*gomapb.ExecReq_Input{
			clangToolchainInput,
			localFiles.mustInput(ctx, t, cluster.adapter.GomaFile, "/b/c/w/include/hello.h", "../../include/hello.h"),
			localFiles.mustInput(ctx, t, cluster.adapter.GomaFile, "/b/c/w/src/hello.c", "../../src/hello.c"),
		},
		Subprogram:        []*gomapb.SubprogramSpec{},
		ToolchainIncluded: proto.Bool(true),
		ToolchainSpecs: []*gomapb.ToolchainSpec{
			{
				Path:         proto.String("../../bin/clang"),
				Hash:         proto.String(clangHashKey),
				Size:         clangToolchainInput.Content.FileSize,
				IsExecutable: proto.Bool(true),
			},
		},
		RequesterInfo: &gomapb.RequesterInfo{
			Dimensions: []string{
				"os:linux",
			},
			PathStyle: gomapb.RequesterInfo_POSIX_STYLE.Enum(),
		},
		ExpectedOutputFiles: []string{
			"hello.o",
		},
	}

	resp, err := cluster.adapter.Exec(ctx, req)
	if err != nil {
		t.Fatalf("Exec(ctx, req)=%v; %v; want nil error", resp, err)
	}
	if resp.GetError() != gomapb.ExecResp_OK {
		t.Errorf("Exec error=%v; want=%v", resp.GetError(), gomapb.ExecResp_OK)
	}

	command := cluster.rbe.gotCommand
	if command == nil {
		t.Fatal("gotCommand is nil")
	}
	wantArgs := []string{
		"out/Release/run.sh",
		"../../bin/clang", "-Iinclude",
		"-c", "../../src/hello.c",
		"-o", "hello.o",
	}
	if !cmp.Equal(command.Arguments, wantArgs) {
		t.Errorf("arguments=%q; want=%q", command.Arguments, wantArgs)
	}
	wantEnvs := []*rpb.Command_EnvironmentVariable{
		{
			Name:  "WORK_DIR",
			Value: "out/Release",
		},
	}
	if !cmp.Equal(command.EnvironmentVariables, wantEnvs, cmp.Comparer(proto.Equal)) {
		t.Errorf("environment_variables=%s; want=%s", command.EnvironmentVariables, wantEnvs)
	}

	action := cluster.rbe.gotAction
	if action == nil {
		t.Fatalf("gotAction is nil")
	}
	files, err := dumpDir(ctx, t, cluster.adapter.Client, cluster.adapter.DefaultInstance(), ".", action.InputRootDigest)
	if err != nil {
		t.Fatalf("err %v", err)
	}

	// files and executables might contain extra "out/Release/run.sh".
	wantFiles := []string{"out/Release/run.sh", "bin/clang", "include/hello.h", "src/hello.c"}
	wantExecutables := []string{"bin/clang", "out/Release/run.sh"}

	for _, f := range wantFiles {
		if !files[f].isFile {
			t.Errorf("%q was not found in files, but should: files=%v", f, files)
		}
	}
	for _, e := range wantExecutables {
		if !files[e].isExecutable {
			t.Errorf("%q was not an executable file, but should: files=%v", e, files)
		}
	}

	if got, want := files["out/Release/run.sh"].digest, digest.Bytes("relocatable-wrapper-script", []byte(relocatableWrapperScript)).Digest(); !proto.Equal(got, want) {
		t.Errorf("digest of out/Release/run.sh: %s != %s", got, want)
	}
}

func TestAdaptorHandleArbitraryToolchainSupportNonRelocatable(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	cluster := &fakeCluster{
		rbe: newFakeRBE(),
	}
	err := cluster.setup(ctx, cluster.rbe.instancePrefix)
	if err != nil {
		t.Fatal(err)
	}
	defer cluster.teardown()

	// Instead of adding a new compiler, register toolchain platform.
	err = cluster.pushPlatform(ctx, "docker://grpc.io/goma-dev/container-image@sha256:yyyy", []string{"os:linux"})
	if err != nil {
		t.Fatal(err)
	}

	var localFiles fakeLocalFiles
	localFiles.Add("/b/c/w/bin/clang", randomBigSize())
	localFiles.Add("/b/c/w/include/hello.h", randomSize())
	localFiles.Add("/b/c/w/src/hello.c", randomSize())

	clangToolchainInput := localFiles.mustInput(ctx, t, cluster.adapter.GomaFile, "/b/c/w/bin/clang", "../../bin/clang")
	clangHashKey := localFiles.mustFileHash(ctx, t, "/b/c/w/bin/clang")

	req := &gomapb.ExecReq{
		CommandSpec: &gomapb.CommandSpec{
			Name:              proto.String("clang"),
			Version:           proto.String("1234"),
			Target:            proto.String("x86-64-linux-gnu"),
			BinaryHash:        []byte(clangHashKey),
			LocalCompilerPath: proto.String("../../bin/clang"),
		},
		Arg: []string{
			"../../bin/clang", "-Iinclude",
			"-g", "-c", "../../src/hello.c",
			"-o", "hello.o",
		},
		Env: []string{"PWD=/b/c/w/out/Debug"},
		Cwd: proto.String("/b/c/w/out/Debug"),
		Input: []*gomapb.ExecReq_Input{
			clangToolchainInput,
			localFiles.mustInput(ctx, t, cluster.adapter.GomaFile, "/b/c/w/include/hello.h", "../../include/hello.h"),
			localFiles.mustInput(ctx, t, cluster.adapter.GomaFile, "/b/c/w/src/hello.c", "../../src/hello.c"),
		},
		Subprogram:        []*gomapb.SubprogramSpec{},
		ToolchainIncluded: proto.Bool(true),
		ToolchainSpecs: []*gomapb.ToolchainSpec{
			{
				Path:         proto.String("../../bin/clang"),
				Hash:         proto.String(clangHashKey),
				Size:         clangToolchainInput.Content.FileSize,
				IsExecutable: proto.Bool(true),
			},
		},
		RequesterInfo: &gomapb.RequesterInfo{
			Dimensions: []string{
				"os:linux",
			},
			PathStyle: gomapb.RequesterInfo_POSIX_STYLE.Enum(),
		},
		ExpectedOutputFiles: []string{
			"hello.o",
		},
	}

	resp, err := cluster.adapter.Exec(ctx, req)
	if err != nil {
		t.Fatalf("Exec(ctx, req)=%v; %v; want nil error", resp, err)
	}
	if resp.GetError() != gomapb.ExecResp_OK {
		t.Errorf("Exec error=%v; want=%v", resp.GetError(), gomapb.ExecResp_OK)
	}

	command := cluster.rbe.gotCommand
	if command == nil {
		t.Fatal("gotCommand is nil")
	}
	wantArgs := []string{
		"out/Debug/run.sh",
		"../../bin/clang", "-Iinclude",
		"-g", "-c", "../../src/hello.c",
		"-o", "hello.o",
	}
	if !cmp.Equal(command.Arguments, wantArgs) {
		t.Errorf("arguments=%q; want=%q", command.Arguments, wantArgs)
	}
	wantEnvs := []*rpb.Command_EnvironmentVariable{
		{
			Name:  "PWD",
			Value: "/b/c/w/out/Debug",
		},
		{
			Name:  "WORK_DIR",
			Value: "out/Debug",
		},
	}
	if !cmp.Equal(command.EnvironmentVariables, wantEnvs, cmp.Comparer(proto.Equal)) {
		t.Errorf("environment_variables=%s; want=%s", command.EnvironmentVariables, wantEnvs)
	}
	wantProperties := []*rpb.Platform_Property{
		{
			Name:  "InputRootAbsolutePath",
			Value: "/b/c/w",
		},
		{
			Name:  "container-image",
			Value: "docker://grpc.io/goma-dev/container-image@sha256:yyyy",
		},
	}
	if command.Platform == nil {
		t.Errorf("platform is nil")
	} else if !cmp.Equal(command.Platform.Properties, wantProperties, cmp.Comparer(proto.Equal)) {
		t.Errorf("platform.properties=%s; want=%s", command.Platform.Properties, wantProperties)
	}

	action := cluster.rbe.gotAction
	if action == nil {
		t.Fatalf("gotAction is nil")
	}
	files, err := dumpDir(ctx, t, cluster.adapter.Client, cluster.adapter.DefaultInstance(), ".", action.InputRootDigest)
	if err != nil {
		t.Fatalf("err %v", err)
	}

	// files and executables might contain extra "out/Debug/run.sh".
	wantFiles := []string{"out/Debug/run.sh", "bin/clang", "include/hello.h", "src/hello.c"}
	wantExecutables := []string{"bin/clang", "out/Debug/run.sh"}

	for _, f := range wantFiles {
		if !files[f].isFile {
			t.Errorf("%q was not found in files, but should: files=%v", f, files)
		}
	}
	for _, e := range wantExecutables {
		if !files[e].isExecutable {
			t.Errorf("%q was not an executable file, but should: files=%v", e, files)
		}
	}

	if got, want := files["out/Debug/run.sh"].digest, digest.Bytes("wrapper-script", []byte(relocatableWrapperScript)).Digest(); !proto.Equal(got, want) {
		t.Errorf("digest of out/Debug/run.sh: %s != %s", got, want)
	}
}

// TODO: add test for ATS+chroot case using symlinks.

func TestAdapterDockerProperties(t *testing.T) {
	for _, tc := range []struct {
		desc string
		args []string
		want []*rpb.Platform_Property
	}{
		{
			desc: "relocatable",
			args: nil,
			want: nil,
		},
		{
			desc: "non relocatable",
			args: []string{"-g"},
			want: []*rpb.Platform_Property{
				{
					Name:  "InputRootAbsolutePath",
					Value: "/b/c/w",
				},
			},
		},
	} {
		t.Run(tc.desc, func(t *testing.T) {
			ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
			defer cancel()

			cluster := &fakeCluster{
				rbe: newFakeRBE(),
			}
			err := cluster.setup(ctx, cluster.rbe.instancePrefix)
			if err != nil {
				t.Fatal(err)
			}
			defer cluster.teardown()
			clang := newFakeClang(&cluster.cmdStorage, "1234", "x86-64-linux-gnu")
			err = cluster.pushToolchains(ctx, clang)
			if err != nil {
				t.Fatal(err)
			}
			var localFiles fakeLocalFiles
			localFiles.Add("/b/c/w/src/hello.cc", randomSize())

			req := &gomapb.ExecReq{
				CommandSpec: clang.CommandSpec("clang", "bin/clang"),
				Arg:         append([]string{"bin/clang", "-c", "../../src/hello.cc"}, tc.args...),
				Env:         []string{},
				Cwd:         proto.String("/b/c/w/out/Release"),
				Input: []*gomapb.ExecReq_Input{
					localFiles.mustInput(ctx, t, cluster.adapter.GomaFile, "/b/c/w/src/hello.cc", "../../src/hello.cc"),
				},
				Subprogram:    []*gomapb.SubprogramSpec{},
				RequesterInfo: &gomapb.RequesterInfo{},
				HermeticMode:  proto.Bool(true),
			}
			resp, err := cluster.adapter.Exec(ctx, req)
			if err != nil {
				t.Fatalf("Exec(ctx, req)=%v; %v; want nil error", resp, err)
			}
			if resp.GetError() != gomapb.ExecResp_OK {
				t.Errorf("Exec error=%v; want=%v", resp.GetError(), gomapb.ExecResp_OK)
			}

			command := cluster.rbe.gotCommand
			if command == nil {
				t.Fatalf("gotCommand is nil")
			}
			want := []*rpb.Platform_Property{}
			for _, p := range clang.RemoteexecPlatform.Properties {
				want = append(want, &rpb.Platform_Property{
					Name:  p.Name,
					Value: p.Value,
				})
			}
			want = append(want, tc.want...)
			sort.Slice(want, func(i, j int) bool {
				return want[i].Name < want[j].Name
			})
			if diff := cmp.Diff(want, command.Platform.GetProperties(), cmp.Comparer(proto.Equal)); diff != "" {
				t.Errorf("platform.Properties diff want->got\n%s", diff)
			}
		})
	}
}
