mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 18:53:35 +00:00
Fresh dep ensure
This commit is contained in:
55
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/diff/BUILD
generated
vendored
Normal file
55
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/diff/BUILD
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["diff.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/diff",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/kubectl:go_default_library",
|
||||
"//pkg/kubectl/cmd/apply:go_default_library",
|
||||
"//pkg/kubectl/cmd/util:go_default_library",
|
||||
"//pkg/kubectl/cmd/util/openapi:go_default_library",
|
||||
"//pkg/kubectl/scheme:go_default_library",
|
||||
"//pkg/kubectl/util/i18n:go_default_library",
|
||||
"//pkg/kubectl/util/templates:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:go_default_library",
|
||||
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource:go_default_library",
|
||||
"//vendor/github.com/jonboulle/clockwork:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
"//vendor/sigs.k8s.io/yaml:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["diff_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
436
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/diff/diff.go
generated
vendored
Normal file
436
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/diff/diff.go
generated
vendored
Normal file
@ -0,0 +1,436 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package diff
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/jonboulle/clockwork"
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions/resource"
|
||||
"k8s.io/klog"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/apply"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/templates"
|
||||
"k8s.io/utils/exec"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
var (
|
||||
diffLong = templates.LongDesc(i18n.T(`
|
||||
Diff configurations specified by filename or stdin between the current online
|
||||
configuration, and the configuration as it would be if applied.
|
||||
|
||||
Output is always YAML.
|
||||
|
||||
KUBECTL_EXTERNAL_DIFF environment variable can be used to select your own
|
||||
diff command. By default, the "diff" command available in your path will be
|
||||
run with "-u" (unicode) and "-N" (treat new files as empty) options.`))
|
||||
diffExample = templates.Examples(i18n.T(`
|
||||
# Diff resources included in pod.json.
|
||||
kubectl diff -f pod.json
|
||||
|
||||
# Diff file read from stdin
|
||||
cat service.yaml | kubectl diff -f -`))
|
||||
)
|
||||
|
||||
// Number of times we try to diff before giving-up
|
||||
const maxRetries = 4
|
||||
|
||||
type DiffOptions struct {
|
||||
FilenameOptions resource.FilenameOptions
|
||||
}
|
||||
|
||||
func checkDiffArgs(cmd *cobra.Command, args []string) error {
|
||||
if len(args) != 0 {
|
||||
return cmdutil.UsageErrorf(cmd, "Unexpected args: %v", args)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewCmdDiff(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
var options DiffOptions
|
||||
diff := DiffProgram{
|
||||
Exec: exec.New(),
|
||||
IOStreams: streams,
|
||||
}
|
||||
cmd := &cobra.Command{
|
||||
Use: "diff -f FILENAME",
|
||||
DisableFlagsInUseLine: true,
|
||||
Short: i18n.T("Diff live version against would-be applied version"),
|
||||
Long: diffLong,
|
||||
Example: diffExample,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(checkDiffArgs(cmd, args))
|
||||
cmdutil.CheckErr(RunDiff(f, &diff, &options))
|
||||
},
|
||||
}
|
||||
|
||||
usage := "contains the configuration to diff"
|
||||
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
|
||||
cmd.MarkFlagRequired("filename")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// DiffProgram finds and run the diff program. The value of
|
||||
// KUBECTL_EXTERNAL_DIFF environment variable will be used a diff
|
||||
// program. By default, `diff(1)` will be used.
|
||||
type DiffProgram struct {
|
||||
Exec exec.Interface
|
||||
genericclioptions.IOStreams
|
||||
}
|
||||
|
||||
func (d *DiffProgram) getCommand(args ...string) exec.Cmd {
|
||||
diff := ""
|
||||
if envDiff := os.Getenv("KUBECTL_EXTERNAL_DIFF"); envDiff != "" {
|
||||
diff = envDiff
|
||||
} else {
|
||||
diff = "diff"
|
||||
args = append([]string{"-u", "-N"}, args...)
|
||||
}
|
||||
|
||||
cmd := d.Exec.Command(diff, args...)
|
||||
cmd.SetStdout(d.Out)
|
||||
cmd.SetStderr(d.ErrOut)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// Run runs the detected diff program. `from` and `to` are the directory to diff.
|
||||
func (d *DiffProgram) Run(from, to string) error {
|
||||
return d.getCommand(from, to).Run()
|
||||
}
|
||||
|
||||
// Printer is used to print an object.
|
||||
type Printer struct{}
|
||||
|
||||
// Print the object inside the writer w.
|
||||
func (p *Printer) Print(obj runtime.Object, w io.Writer) error {
|
||||
if obj == nil {
|
||||
return nil
|
||||
}
|
||||
data, err := yaml.Marshal(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = w.Write(data)
|
||||
return err
|
||||
|
||||
}
|
||||
|
||||
// DiffVersion gets the proper version of objects, and aggregate them into a directory.
|
||||
type DiffVersion struct {
|
||||
Dir *Directory
|
||||
Name string
|
||||
}
|
||||
|
||||
// NewDiffVersion creates a new DiffVersion with the named version.
|
||||
func NewDiffVersion(name string) (*DiffVersion, error) {
|
||||
dir, err := CreateDirectory(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &DiffVersion{
|
||||
Dir: dir,
|
||||
Name: name,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (v *DiffVersion) getObject(obj Object) (runtime.Object, error) {
|
||||
switch v.Name {
|
||||
case "LIVE":
|
||||
return obj.Live(), nil
|
||||
case "MERGED":
|
||||
return obj.Merged()
|
||||
}
|
||||
return nil, fmt.Errorf("Unknown version: %v", v.Name)
|
||||
}
|
||||
|
||||
// Print prints the object using the printer into a new file in the directory.
|
||||
func (v *DiffVersion) Print(obj Object, printer Printer) error {
|
||||
vobj, err := v.getObject(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := v.Dir.NewFile(obj.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
return printer.Print(vobj, f)
|
||||
}
|
||||
|
||||
// Directory creates a new temp directory, and allows to easily create new files.
|
||||
type Directory struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
// CreateDirectory does create the actual disk directory, and return a
|
||||
// new representation of it.
|
||||
func CreateDirectory(prefix string) (*Directory, error) {
|
||||
name, err := ioutil.TempDir("", prefix+"-")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Directory{
|
||||
Name: name,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewFile creates a new file in the directory.
|
||||
func (d *Directory) NewFile(name string) (*os.File, error) {
|
||||
return os.OpenFile(filepath.Join(d.Name, name), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0700)
|
||||
}
|
||||
|
||||
// Delete removes the directory recursively.
|
||||
func (d *Directory) Delete() error {
|
||||
return os.RemoveAll(d.Name)
|
||||
}
|
||||
|
||||
// Object is an interface that let's you retrieve multiple version of
|
||||
// it.
|
||||
type Object interface {
|
||||
Live() runtime.Object
|
||||
Merged() (runtime.Object, error)
|
||||
|
||||
Name() string
|
||||
}
|
||||
|
||||
// InfoObject is an implementation of the Object interface. It gets all
|
||||
// the information from the Info object.
|
||||
type InfoObject struct {
|
||||
LocalObj runtime.Object
|
||||
Info *resource.Info
|
||||
Encoder runtime.Encoder
|
||||
OpenAPI openapi.Resources
|
||||
Force bool
|
||||
}
|
||||
|
||||
var _ Object = &InfoObject{}
|
||||
|
||||
// Returns the live version of the object
|
||||
func (obj InfoObject) Live() runtime.Object {
|
||||
return obj.Info.Object
|
||||
}
|
||||
|
||||
// Returns the "merged" object, as it would look like if applied or
|
||||
// created.
|
||||
func (obj InfoObject) Merged() (runtime.Object, error) {
|
||||
// Build the patcher, and then apply the patch with dry-run, unless the object doesn't exist, in which case we need to create it.
|
||||
if obj.Live() == nil {
|
||||
// Dry-run create if the object doesn't exist.
|
||||
return resource.NewHelper(obj.Info.Client, obj.Info.Mapping).Create(
|
||||
obj.Info.Namespace,
|
||||
true,
|
||||
obj.LocalObj,
|
||||
&metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}},
|
||||
)
|
||||
}
|
||||
|
||||
var resourceVersion *string
|
||||
if !obj.Force {
|
||||
accessor, err := meta.Accessor(obj.Info.Object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
str := accessor.GetResourceVersion()
|
||||
resourceVersion = &str
|
||||
}
|
||||
|
||||
modified, err := kubectl.GetModifiedConfiguration(obj.LocalObj, false, unstructured.UnstructuredJSONScheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// This is using the patcher from apply, to keep the same behavior.
|
||||
// We plan on replacing this with server-side apply when it becomes available.
|
||||
patcher := &apply.Patcher{
|
||||
Mapping: obj.Info.Mapping,
|
||||
Helper: resource.NewHelper(obj.Info.Client, obj.Info.Mapping),
|
||||
Overwrite: true,
|
||||
BackOff: clockwork.NewRealClock(),
|
||||
ServerDryRun: true,
|
||||
OpenapiSchema: obj.OpenAPI,
|
||||
ResourceVersion: resourceVersion,
|
||||
}
|
||||
|
||||
_, result, err := patcher.Patch(obj.Info.Object, modified, obj.Info.Source, obj.Info.Namespace, obj.Info.Name, nil)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (obj InfoObject) Name() string {
|
||||
return obj.Info.Name
|
||||
}
|
||||
|
||||
// Differ creates two DiffVersion and diffs them.
|
||||
type Differ struct {
|
||||
From *DiffVersion
|
||||
To *DiffVersion
|
||||
}
|
||||
|
||||
func NewDiffer(from, to string) (*Differ, error) {
|
||||
differ := Differ{}
|
||||
var err error
|
||||
differ.From, err = NewDiffVersion(from)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
differ.To, err = NewDiffVersion(to)
|
||||
if err != nil {
|
||||
differ.From.Dir.Delete()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &differ, nil
|
||||
}
|
||||
|
||||
// Diff diffs to versions of a specific object, and print both versions to directories.
|
||||
func (d *Differ) Diff(obj Object, printer Printer) error {
|
||||
if err := d.From.Print(obj, printer); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := d.To.Print(obj, printer); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Run runs the diff program against both directories.
|
||||
func (d *Differ) Run(diff *DiffProgram) error {
|
||||
return diff.Run(d.From.Dir.Name, d.To.Dir.Name)
|
||||
}
|
||||
|
||||
// TearDown removes both temporary directories recursively.
|
||||
func (d *Differ) TearDown() {
|
||||
d.From.Dir.Delete() // Ignore error
|
||||
d.To.Dir.Delete() // Ignore error
|
||||
}
|
||||
|
||||
func isConflict(err error) bool {
|
||||
return err != nil && errors.IsConflict(err)
|
||||
}
|
||||
|
||||
// RunDiff uses the factory to parse file arguments, find the version to
|
||||
// diff, and find each Info object for each files, and runs against the
|
||||
// differ.
|
||||
func RunDiff(f cmdutil.Factory, diff *DiffProgram, options *DiffOptions) error {
|
||||
schema, err := f.OpenAPISchema()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
discovery, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dynamic, err := f.DynamicClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dryRunVerifier := &apply.DryRunVerifier{
|
||||
Finder: cmdutil.NewCRDFinder(cmdutil.CRDFromDynamic(dynamic)),
|
||||
OpenAPIGetter: discovery,
|
||||
}
|
||||
|
||||
differ, err := NewDiffer("LIVE", "MERGED")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer differ.TearDown()
|
||||
|
||||
printer := Printer{}
|
||||
|
||||
cmdNamespace, enforceNamespace, err := f.ToRawKubeConfigLoader().Namespace()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r := f.NewBuilder().
|
||||
Unstructured().
|
||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||
FilenameParam(enforceNamespace, &options.FilenameOptions).
|
||||
Flatten().
|
||||
Do()
|
||||
if err := r.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = r.Visit(func(info *resource.Info, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := dryRunVerifier.HasSupport(info.Mapping.GroupVersionKind); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
local := info.Object.DeepCopyObject()
|
||||
for i := 1; i <= maxRetries; i++ {
|
||||
if err = info.Get(); err != nil {
|
||||
if !errors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
info.Object = nil
|
||||
}
|
||||
|
||||
force := i == maxRetries
|
||||
if force {
|
||||
klog.Warningf(
|
||||
"Object (%v: %v) keeps changing, diffing without lock",
|
||||
info.Object.GetObjectKind().GroupVersionKind(),
|
||||
info.Name,
|
||||
)
|
||||
}
|
||||
obj := InfoObject{
|
||||
LocalObj: local,
|
||||
Info: info,
|
||||
Encoder: scheme.DefaultJSONEncoder(),
|
||||
OpenAPI: schema,
|
||||
Force: force,
|
||||
}
|
||||
|
||||
err = differ.Diff(obj, printer)
|
||||
if !isConflict(err) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return differ.Run(diff)
|
||||
}
|
196
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/diff/diff_test.go
generated
vendored
Normal file
196
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/diff/diff_test.go
generated
vendored
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package diff
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/utils/exec"
|
||||
)
|
||||
|
||||
type FakeObject struct {
|
||||
name string
|
||||
merged map[string]interface{}
|
||||
live map[string]interface{}
|
||||
}
|
||||
|
||||
var _ Object = &FakeObject{}
|
||||
|
||||
func (f *FakeObject) Name() string {
|
||||
return f.name
|
||||
}
|
||||
|
||||
func (f *FakeObject) Merged() (runtime.Object, error) {
|
||||
return &unstructured.Unstructured{Object: f.merged}, nil
|
||||
}
|
||||
|
||||
func (f *FakeObject) Live() runtime.Object {
|
||||
return &unstructured.Unstructured{Object: f.live}
|
||||
}
|
||||
|
||||
func TestDiffProgram(t *testing.T) {
|
||||
os.Setenv("KUBECTL_EXTERNAL_DIFF", "echo")
|
||||
streams, _, stdout, _ := genericclioptions.NewTestIOStreams()
|
||||
diff := DiffProgram{
|
||||
IOStreams: streams,
|
||||
Exec: exec.New(),
|
||||
}
|
||||
err := diff.Run("one", "two")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if output := stdout.String(); output != "one two\n" {
|
||||
t.Fatalf(`stdout = %q, expected "one two\n"`, output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrinter(t *testing.T) {
|
||||
printer := Printer{}
|
||||
|
||||
obj := &unstructured.Unstructured{Object: map[string]interface{}{
|
||||
"string": "string",
|
||||
"list": []int{1, 2, 3},
|
||||
"int": 12,
|
||||
}}
|
||||
buf := bytes.Buffer{}
|
||||
printer.Print(obj, &buf)
|
||||
want := `int: 12
|
||||
list:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
string: string
|
||||
`
|
||||
if buf.String() != want {
|
||||
t.Errorf("Print() = %q, want %q", buf.String(), want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDiffVersion(t *testing.T) {
|
||||
diff, err := NewDiffVersion("MERGED")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer diff.Dir.Delete()
|
||||
|
||||
obj := FakeObject{
|
||||
name: "bla",
|
||||
live: map[string]interface{}{"live": true},
|
||||
merged: map[string]interface{}{"merged": true},
|
||||
}
|
||||
err = diff.Print(&obj, Printer{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fcontent, err := ioutil.ReadFile(path.Join(diff.Dir.Name, obj.Name()))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
econtent := "merged: true\n"
|
||||
if string(fcontent) != econtent {
|
||||
t.Fatalf("File has %q, expected %q", string(fcontent), econtent)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDirectory(t *testing.T) {
|
||||
dir, err := CreateDirectory("prefix")
|
||||
defer dir.Delete()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = os.Stat(dir.Name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.HasPrefix(filepath.Base(dir.Name), "prefix") {
|
||||
t.Fatalf(`Directory doesn't start with "prefix": %q`, dir.Name)
|
||||
}
|
||||
entries, err := ioutil.ReadDir(dir.Name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(entries) != 0 {
|
||||
t.Fatalf("Directory should be empty, has %d elements", len(entries))
|
||||
}
|
||||
_, err = dir.NewFile("ONE")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = dir.NewFile("TWO")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
entries, err = ioutil.ReadDir(dir.Name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(entries) != 2 {
|
||||
t.Fatalf("ReadDir should have two elements, has %d elements", len(entries))
|
||||
}
|
||||
err = dir.Delete()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = os.Stat(dir.Name)
|
||||
if err == nil {
|
||||
t.Fatal("Directory should be gone, still present.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDiffer(t *testing.T) {
|
||||
diff, err := NewDiffer("LIVE", "MERGED")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer diff.TearDown()
|
||||
|
||||
obj := FakeObject{
|
||||
name: "bla",
|
||||
live: map[string]interface{}{"live": true},
|
||||
merged: map[string]interface{}{"merged": true},
|
||||
}
|
||||
err = diff.Diff(&obj, Printer{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fcontent, err := ioutil.ReadFile(path.Join(diff.From.Dir.Name, obj.Name()))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
econtent := "live: true\n"
|
||||
if string(fcontent) != econtent {
|
||||
t.Fatalf("File has %q, expected %q", string(fcontent), econtent)
|
||||
}
|
||||
|
||||
fcontent, err = ioutil.ReadFile(path.Join(diff.To.Dir.Name, obj.Name()))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
econtent = "merged: true\n"
|
||||
if string(fcontent) != econtent {
|
||||
t.Fatalf("File has %q, expected %q", string(fcontent), econtent)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user