test

package
v1.4.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 17, 2016 License: MIT Imports: 13 Imported by: 0

README

Git LFS Tests

Git LFS uses two form of tests: unit tests for the internals written in Go, and integration tests that run git and git-lfs in a real shell environment. You can run them separately:

$ script/test        # Tests the Go packages.
$ script/integration # Tests the commands in shell scripts.

CI servers should always run both:

$ script/cibuild

Internal Package Tests

The internal tests use Go's builtin testing package.

You can run individual tests by passing arguments to script/test:

# test a specific Go package
$ script/test lfs

# pass other `go test` arguments
$ script/test lfs -run TestSuccessStatus -v
github.com/kr/text
github.com/cheggaaa/pb
github.com/rubyist/tracerx
github.com/kr/pretty
github.com/github/git-lfs/git
github.com/technoweenie/assert
=== RUN TestSuccessStatus
--- PASS: TestSuccessStatus (0.00 seconds)
PASS
ok  	_/Users/rick/github/git-lfs/lfs	0.011s

Integration Tests

Git LFS integration tests are shell scripts that test the git-lfs command from the shell. Each test file can be run individually, or in parallel through script/integration. Some tests will change the pwd, so it's important that they run in separate OS processes.

$ test/test-happy-path.sh
compile git-lfs for test/test-happy-path.sh
LFSTEST_URL=/Users/rick/github/git-lfs/test/remote/url LFSTEST_DIR=/Users/rick/github/git-lfs/test/remote lfstest-gitserver
test: happy path ...                                               OK
  1. The integration tests should not rely on global system or git config.
  2. The tests should be cross platform (Linux, Mac, Windows).
  3. Tests should bootstrap an isolated, clean environment. See the Test Suite section.
  4. Successful test runs should have minimal output.
  5. Failing test runs should dump enough information to diagnose the bug. This includes stdout, stderr, any log files, and even the OS environment.

There are a few environment variables that you can set to change the test suite behavior:

  • GIT_LFS_TEST_DIR=path - This sets the directory that is used as the current working directory of the tests. By default, this will be in your temp dir. It's recommended that this is set to a directory outside of any Git repository.
  • GIT_LFS_TEST_MAXPROCS=N - This tells script/integration how many tests to run in parallel. Default: 4.
  • KEEPTRASH=1 - This will leave the local repository data in a tmp directory and the remote repository data in test/remote.
  • SKIPCOMPILE=1 - This skips the Git LFS compilation step. Speeds up the tests when you're running the same test script multiple times without changing any Go code.

Also ensure that your noproxy environment variable contains 127.0.0.1 host, to allow git commands to reach the local Git server lfstest-gitserver.

Test Suite

The testenv.sh script includes some global variables used in tests. This should be automatically included in every test/test-*.sh script and script/integration.

testhelpers.sh defines some shell functions. Most are only used in the test scripts themselves. script/integration uses the setup() and shutdown() functions.

testlib.sh is a fork of a lightweight shell testing lib that is used internally at GitHub. Only the test/test-*.sh scripts should include this.

Tests live in this ./test directory, and must have a unique name like: test-{name}.sh. All tests should start with a basic template. See test/test-happy-path.sh for an example.

#!/usr/bin/env bash

. "test/testlib.sh"

begin_test "template"
(
  set -e

  echo "your tests go here"
)
end_test

The set -e command will bail on the test at the first command that returns a non zero exit status. Use simple shell commands like grep as assertions.

The test suite has standard setup and shutdown functions that should be run only once. If a test script is run by script/integration, it will skip the functions. Setup does the following:

  • Resets temporary test directories.
  • Compiles git-lfs with the latest code changes.
  • Compiles Go files in test/cmd to bin, and adds them the PATH.
  • Spins up a test Git and Git LFS server so the entire push/pull flow can be exercised.
  • Sets up a git credential helper that always returns a set username and password.

The test Git server writes a test/remote/url file when it's complete. This file is how individual test scripts detect if script/integration is being run. You can fake this by manually spinning up the Git server using the lfstest-gitserver line that is output after Git LFS is compiled.

By default, temporary directories in tmp and the test/remote directory are cleared after test runs. Send the "KEEPTRASH" if you want to keep these files around for debugging failed tests.

Documentation

Index

Constants

View Source
const (
	// Normal repo with working copy
	RepoTypeNormal = RepoType(iota)
	// Bare repo (no working copy)
	RepoTypeBare = RepoType(iota)
	// Repo with working copy but git dir is separate
	RepoTypeSeparateDir = RepoType(iota)
)

Variables

This section is empty.

Functions

func RunGitCommand

func RunGitCommand(callback RepoCallback, failureCheck bool, args ...string) string

Simplistic fire & forget running of git command - returns combined output

Types

type CommitInput

type CommitInput struct {
	// Date that we should commit on (optional, leave blank for 'now')
	CommitDate time.Time
	// List of files to include in this commit
	Files []*FileInput
	// List of parent branches (all branches must have been created in a previous NewBranch or be master)
	// Can be omitted to just use the parent of the previous commit
	ParentBranches []string
	// Name of a new branch we should create at this commit (optional - master not required)
	NewBranch string
	// Names of any tags we should create at this commit (optional)
	Tags []string
	// Name of committer
	CommitterName string
	// Email of committer
	CommitterEmail string
}

Input for defining commits for test repo

type CommitOutput

type CommitOutput struct {
	Sha     string
	Parents []string
	Files   []*lfs.Pointer
}

Output struct with details of commits created for test

type FileInput

type FileInput struct {
	// Name of file (required)
	Filename string
	// Size of file (required)
	Size int64
	// Input data (optional, if provided will be source of data)
	DataReader io.Reader
	// Input data (optional, if provided will be source of data)
	Data string
}

Input data for a single file in a commit

type PlaceholderDataReader

type PlaceholderDataReader struct {
	// contains filtered or unexported fields
}

Just a psuedo-random stream of bytes (not cryptographic) Calls RNG a bit less often than using rand.Source directly

func NewPlaceholderDataReader

func NewPlaceholderDataReader(seed, size int64) *PlaceholderDataReader

func (*PlaceholderDataReader) Read

func (r *PlaceholderDataReader) Read(p []byte) (int, error)

type PointersByOid added in v1.1.0

type PointersByOid []*lfs.Pointer

PointersByOid implements sort.Interface for []*lfs.Pointer based on oid

func (PointersByOid) Len added in v1.1.0

func (a PointersByOid) Len() int

func (PointersByOid) Less added in v1.1.0

func (a PointersByOid) Less(i, j int) bool

func (PointersByOid) Swap added in v1.1.0

func (a PointersByOid) Swap(i, j int)

type RefsByName

type RefsByName []*git.Ref

RefsByName implements sort.Interface for []*git.Ref based on name

func (RefsByName) Len

func (a RefsByName) Len() int

func (RefsByName) Less

func (a RefsByName) Less(i, j int) bool

func (RefsByName) Swap

func (a RefsByName) Swap(i, j int)

type Repo

type Repo struct {
	// Path to the repo, working copy if non-bare
	Path string
	// Path to the git dir
	GitDir string
	// Paths to remotes
	Remotes map[string]*Repo
	// Settings used to create this repo
	Settings *RepoCreateSettings
	// contains filtered or unexported fields
}

func NewCustomRepo

func NewCustomRepo(callback RepoCallback, settings *RepoCreateSettings) *Repo

NewCustomRepo creates a new git repo in a new temp dir with more control over settings

func NewRepo

func NewRepo(callback RepoCallback) *Repo

NewRepo creates a new git repo in a new temp dir

func WrapRepo

func WrapRepo(c RepoCallback, path string) *Repo

WrapRepo creates a new Repo instance for an existing git repo

func (*Repo) AddCommits

func (repo *Repo) AddCommits(inputs []*CommitInput) []*CommitOutput

func (*Repo) AddRemote

func (r *Repo) AddRemote(name string) *Repo

Add a new remote (generate a path for it to live in, will be cleaned up)

func (*Repo) Cleanup

func (r *Repo) Cleanup()

func (*Repo) Popd

func (r *Repo) Popd()

func (*Repo) Pushd

func (r *Repo) Pushd()

Change to repo dir but save current dir

type RepoCallback

type RepoCallback interface {
	// Fatalf reports error and fails
	Fatalf(format string, args ...interface{})
	// Errorf reports error and continues
	Errorf(format string, args ...interface{})
}

Callback interface (testing.T compatible)

type RepoCreateSettings

type RepoCreateSettings struct {
	RepoType RepoType
}

type RepoType

type RepoType int

type WrappedPointersByOid

type WrappedPointersByOid []*lfs.WrappedPointer

WrappedPointersByOid implements sort.Interface for []*lfs.WrappedPointer based on oid

func (WrappedPointersByOid) Len

func (a WrappedPointersByOid) Len() int

func (WrappedPointersByOid) Less

func (a WrappedPointersByOid) Less(i, j int) bool

func (WrappedPointersByOid) Swap

func (a WrappedPointersByOid) Swap(i, j int)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL