vendor: Update vendoring for the exec client and server implementations
Signed-off-by: Jacek J. Łakis <jacek.lakis@intel.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
parent
d25b88583f
commit
bf51655a7b
2124 changed files with 809703 additions and 5 deletions
42
vendor/google.golang.org/appengine/aetest/doc.go
generated
vendored
Normal file
42
vendor/google.golang.org/appengine/aetest/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
Package aetest provides an API for running dev_appserver for use in tests.
|
||||
|
||||
An example test file:
|
||||
|
||||
package foo_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"google.golang.org/appengine/memcache"
|
||||
"google.golang.org/appengine/aetest"
|
||||
)
|
||||
|
||||
func TestFoo(t *testing.T) {
|
||||
ctx, done, err := aetest.NewContext()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
it := &memcache.Item{
|
||||
Key: "some-key",
|
||||
Value: []byte("some-value"),
|
||||
}
|
||||
err = memcache.Set(ctx, it)
|
||||
if err != nil {
|
||||
t.Fatalf("Set err: %v", err)
|
||||
}
|
||||
it, err = memcache.Get(ctx, "some-key")
|
||||
if err != nil {
|
||||
t.Fatalf("Get err: %v; want no error", err)
|
||||
}
|
||||
if g, w := string(it.Value), "some-value" ; g != w {
|
||||
t.Errorf("retrieved Item.Value = %q, want %q", g, w)
|
||||
}
|
||||
}
|
||||
|
||||
The environment variable APPENGINE_DEV_APPSERVER specifies the location of the
|
||||
dev_appserver.py executable to use. If unset, the system PATH is consulted.
|
||||
*/
|
||||
package aetest
|
51
vendor/google.golang.org/appengine/aetest/instance.go
generated
vendored
Normal file
51
vendor/google.golang.org/appengine/aetest/instance.go
generated
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
package aetest
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/appengine"
|
||||
)
|
||||
|
||||
// Instance represents a running instance of the development API Server.
|
||||
type Instance interface {
|
||||
// Close kills the child api_server.py process, releasing its resources.
|
||||
io.Closer
|
||||
// NewRequest returns an *http.Request associated with this instance.
|
||||
NewRequest(method, urlStr string, body io.Reader) (*http.Request, error)
|
||||
}
|
||||
|
||||
// Options is used to specify options when creating an Instance.
|
||||
type Options struct {
|
||||
// AppID specifies the App ID to use during tests.
|
||||
// By default, "testapp".
|
||||
AppID string
|
||||
// StronglyConsistentDatastore is whether the local datastore should be
|
||||
// strongly consistent. This will diverge from production behaviour.
|
||||
StronglyConsistentDatastore bool
|
||||
}
|
||||
|
||||
// NewContext starts an instance of the development API server, and returns
|
||||
// a context that will route all API calls to that server, as well as a
|
||||
// closure that must be called when the Context is no longer required.
|
||||
func NewContext() (context.Context, func(), error) {
|
||||
inst, err := NewInstance(nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
req, err := inst.NewRequest("GET", "/", nil)
|
||||
if err != nil {
|
||||
inst.Close()
|
||||
return nil, nil, err
|
||||
}
|
||||
ctx := appengine.NewContext(req)
|
||||
return ctx, func() {
|
||||
inst.Close()
|
||||
}, nil
|
||||
}
|
||||
|
||||
// PrepareDevAppserver is a hook which, if set, will be called before the
|
||||
// dev_appserver.py is started, each time it is started. If aetest.NewContext
|
||||
// is invoked from the goapp test tool, this hook is unnecessary.
|
||||
var PrepareDevAppserver func() error
|
21
vendor/google.golang.org/appengine/aetest/instance_classic.go
generated
vendored
Normal file
21
vendor/google.golang.org/appengine/aetest/instance_classic.go
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
// +build appengine
|
||||
|
||||
package aetest
|
||||
|
||||
import "appengine/aetest"
|
||||
|
||||
// NewInstance launches a running instance of api_server.py which can be used
|
||||
// for multiple test Contexts that delegate all App Engine API calls to that
|
||||
// instance.
|
||||
// If opts is nil the default values are used.
|
||||
func NewInstance(opts *Options) (Instance, error) {
|
||||
aetest.PrepareDevAppserver = PrepareDevAppserver
|
||||
var aeOpts *aetest.Options
|
||||
if opts != nil {
|
||||
aeOpts = &aetest.Options{
|
||||
AppID: opts.AppID,
|
||||
StronglyConsistentDatastore: opts.StronglyConsistentDatastore,
|
||||
}
|
||||
}
|
||||
return aetest.NewInstance(aeOpts)
|
||||
}
|
116
vendor/google.golang.org/appengine/aetest/instance_test.go
generated
vendored
Normal file
116
vendor/google.golang.org/appengine/aetest/instance_test.go
generated
vendored
Normal file
|
@ -0,0 +1,116 @@
|
|||
package aetest
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"google.golang.org/appengine"
|
||||
"google.golang.org/appengine/datastore"
|
||||
"google.golang.org/appengine/memcache"
|
||||
"google.golang.org/appengine/user"
|
||||
)
|
||||
|
||||
func TestBasicAPICalls(t *testing.T) {
|
||||
// Only run the test if APPENGINE_DEV_APPSERVER is explicitly set.
|
||||
if os.Getenv("APPENGINE_DEV_APPSERVER") == "" {
|
||||
t.Skip("APPENGINE_DEV_APPSERVER not set")
|
||||
}
|
||||
|
||||
inst, err := NewInstance(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("NewInstance: %v", err)
|
||||
}
|
||||
defer inst.Close()
|
||||
|
||||
req, err := inst.NewRequest("GET", "http://example.com/page", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("NewRequest: %v", err)
|
||||
}
|
||||
ctx := appengine.NewContext(req)
|
||||
|
||||
it := &memcache.Item{
|
||||
Key: "some-key",
|
||||
Value: []byte("some-value"),
|
||||
}
|
||||
err = memcache.Set(ctx, it)
|
||||
if err != nil {
|
||||
t.Fatalf("Set err: %v", err)
|
||||
}
|
||||
it, err = memcache.Get(ctx, "some-key")
|
||||
if err != nil {
|
||||
t.Fatalf("Get err: %v; want no error", err)
|
||||
}
|
||||
if g, w := string(it.Value), "some-value"; g != w {
|
||||
t.Errorf("retrieved Item.Value = %q, want %q", g, w)
|
||||
}
|
||||
|
||||
type Entity struct{ Value string }
|
||||
e := &Entity{Value: "foo"}
|
||||
k := datastore.NewIncompleteKey(ctx, "Entity", nil)
|
||||
k, err = datastore.Put(ctx, k, e)
|
||||
if err != nil {
|
||||
t.Fatalf("datastore.Put: %v", err)
|
||||
}
|
||||
e = new(Entity)
|
||||
if err := datastore.Get(ctx, k, e); err != nil {
|
||||
t.Fatalf("datastore.Get: %v", err)
|
||||
}
|
||||
if g, w := e.Value, "foo"; g != w {
|
||||
t.Errorf("retrieved Entity.Value = %q, want %q", g, w)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext(t *testing.T) {
|
||||
// Only run the test if APPENGINE_DEV_APPSERVER is explicitly set.
|
||||
if os.Getenv("APPENGINE_DEV_APPSERVER") == "" {
|
||||
t.Skip("APPENGINE_DEV_APPSERVER not set")
|
||||
}
|
||||
|
||||
// Check that the context methods work.
|
||||
_, done, err := NewContext()
|
||||
if err != nil {
|
||||
t.Fatalf("NewContext: %v", err)
|
||||
}
|
||||
done()
|
||||
}
|
||||
|
||||
func TestUsers(t *testing.T) {
|
||||
// Only run the test if APPENGINE_DEV_APPSERVER is explicitly set.
|
||||
if os.Getenv("APPENGINE_DEV_APPSERVER") == "" {
|
||||
t.Skip("APPENGINE_DEV_APPSERVER not set")
|
||||
}
|
||||
|
||||
inst, err := NewInstance(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("NewInstance: %v", err)
|
||||
}
|
||||
defer inst.Close()
|
||||
|
||||
req, err := inst.NewRequest("GET", "http://example.com/page", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("NewRequest: %v", err)
|
||||
}
|
||||
ctx := appengine.NewContext(req)
|
||||
|
||||
if user := user.Current(ctx); user != nil {
|
||||
t.Errorf("user.Current initially %v, want nil", user)
|
||||
}
|
||||
|
||||
u := &user.User{
|
||||
Email: "gopher@example.com",
|
||||
Admin: true,
|
||||
}
|
||||
Login(u, req)
|
||||
|
||||
if got := user.Current(ctx); got.Email != u.Email {
|
||||
t.Errorf("user.Current: %v, want %v", got, u)
|
||||
}
|
||||
if admin := user.IsAdmin(ctx); !admin {
|
||||
t.Errorf("user.IsAdmin: %t, want true", admin)
|
||||
}
|
||||
|
||||
Logout(req)
|
||||
if user := user.Current(ctx); user != nil {
|
||||
t.Errorf("user.Current after logout %v, want nil", user)
|
||||
}
|
||||
}
|
276
vendor/google.golang.org/appengine/aetest/instance_vm.go
generated
vendored
Normal file
276
vendor/google.golang.org/appengine/aetest/instance_vm.go
generated
vendored
Normal file
|
@ -0,0 +1,276 @@
|
|||
// +build !appengine
|
||||
|
||||
package aetest
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/appengine/internal"
|
||||
)
|
||||
|
||||
// NewInstance launches a running instance of api_server.py which can be used
|
||||
// for multiple test Contexts that delegate all App Engine API calls to that
|
||||
// instance.
|
||||
// If opts is nil the default values are used.
|
||||
func NewInstance(opts *Options) (Instance, error) {
|
||||
i := &instance{
|
||||
opts: opts,
|
||||
appID: "testapp",
|
||||
}
|
||||
if opts != nil && opts.AppID != "" {
|
||||
i.appID = opts.AppID
|
||||
}
|
||||
if err := i.startChild(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func newSessionID() string {
|
||||
var buf [16]byte
|
||||
io.ReadFull(rand.Reader, buf[:])
|
||||
return fmt.Sprintf("%x", buf[:])
|
||||
}
|
||||
|
||||
// instance implements the Instance interface.
|
||||
type instance struct {
|
||||
opts *Options
|
||||
child *exec.Cmd
|
||||
apiURL *url.URL // base URL of API HTTP server
|
||||
adminURL string // base URL of admin HTTP server
|
||||
appDir string
|
||||
appID string
|
||||
relFuncs []func() // funcs to release any associated contexts
|
||||
}
|
||||
|
||||
// NewRequest returns an *http.Request associated with this instance.
|
||||
func (i *instance) NewRequest(method, urlStr string, body io.Reader) (*http.Request, error) {
|
||||
req, err := http.NewRequest(method, urlStr, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Associate this request.
|
||||
release := internal.RegisterTestRequest(req, i.apiURL, func(ctx context.Context) context.Context {
|
||||
ctx = internal.WithAppIDOverride(ctx, "dev~"+i.appID)
|
||||
return ctx
|
||||
})
|
||||
i.relFuncs = append(i.relFuncs, release)
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// Close kills the child api_server.py process, releasing its resources.
|
||||
func (i *instance) Close() (err error) {
|
||||
for _, rel := range i.relFuncs {
|
||||
rel()
|
||||
}
|
||||
i.relFuncs = nil
|
||||
if i.child == nil {
|
||||
return nil
|
||||
}
|
||||
defer func() {
|
||||
i.child = nil
|
||||
err1 := os.RemoveAll(i.appDir)
|
||||
if err == nil {
|
||||
err = err1
|
||||
}
|
||||
}()
|
||||
|
||||
if p := i.child.Process; p != nil {
|
||||
errc := make(chan error, 1)
|
||||
go func() {
|
||||
errc <- i.child.Wait()
|
||||
}()
|
||||
|
||||
// Call the quit handler on the admin server.
|
||||
res, err := http.Get(i.adminURL + "/quit")
|
||||
if err != nil {
|
||||
p.Kill()
|
||||
return fmt.Errorf("unable to call /quit handler: %v", err)
|
||||
}
|
||||
res.Body.Close()
|
||||
|
||||
select {
|
||||
case <-time.After(15 * time.Second):
|
||||
p.Kill()
|
||||
return errors.New("timeout killing child process")
|
||||
case err = <-errc:
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func fileExists(path string) bool {
|
||||
_, err := os.Stat(path)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func findPython() (path string, err error) {
|
||||
for _, name := range []string{"python2.7", "python"} {
|
||||
path, err = exec.LookPath(name)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func findDevAppserver() (string, error) {
|
||||
if p := os.Getenv("APPENGINE_DEV_APPSERVER"); p != "" {
|
||||
if fileExists(p) {
|
||||
return p, nil
|
||||
}
|
||||
return "", fmt.Errorf("invalid APPENGINE_DEV_APPSERVER environment variable; path %q doesn't exist", p)
|
||||
}
|
||||
return exec.LookPath("dev_appserver.py")
|
||||
}
|
||||
|
||||
var apiServerAddrRE = regexp.MustCompile(`Starting API server at: (\S+)`)
|
||||
var adminServerAddrRE = regexp.MustCompile(`Starting admin server at: (\S+)`)
|
||||
|
||||
func (i *instance) startChild() (err error) {
|
||||
if PrepareDevAppserver != nil {
|
||||
if err := PrepareDevAppserver(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
python, err := findPython()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not find python interpreter: %v", err)
|
||||
}
|
||||
devAppserver, err := findDevAppserver()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not find dev_appserver.py: %v", err)
|
||||
}
|
||||
|
||||
i.appDir, err = ioutil.TempDir("", "appengine-aetest")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
os.RemoveAll(i.appDir)
|
||||
}
|
||||
}()
|
||||
err = os.Mkdir(filepath.Join(i.appDir, "app"), 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(filepath.Join(i.appDir, "app", "app.yaml"), []byte(i.appYAML()), 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(filepath.Join(i.appDir, "app", "stubapp.go"), []byte(appSource), 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
appserverArgs := []string{
|
||||
devAppserver,
|
||||
"--port=0",
|
||||
"--api_port=0",
|
||||
"--admin_port=0",
|
||||
"--automatic_restart=false",
|
||||
"--skip_sdk_update_check=true",
|
||||
"--clear_datastore=true",
|
||||
"--clear_search_indexes=true",
|
||||
"--datastore_path", filepath.Join(i.appDir, "datastore"),
|
||||
}
|
||||
if i.opts != nil && i.opts.StronglyConsistentDatastore {
|
||||
appserverArgs = append(appserverArgs, "--datastore_consistency_policy=consistent")
|
||||
}
|
||||
appserverArgs = append(appserverArgs, filepath.Join(i.appDir, "app"))
|
||||
|
||||
i.child = exec.Command(python,
|
||||
appserverArgs...,
|
||||
)
|
||||
i.child.Stdout = os.Stdout
|
||||
var stderr io.Reader
|
||||
stderr, err = i.child.StderrPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stderr = io.TeeReader(stderr, os.Stderr)
|
||||
if err = i.child.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Read stderr until we have read the URLs of the API server and admin interface.
|
||||
errc := make(chan error, 1)
|
||||
go func() {
|
||||
s := bufio.NewScanner(stderr)
|
||||
for s.Scan() {
|
||||
if match := apiServerAddrRE.FindStringSubmatch(s.Text()); match != nil {
|
||||
u, err := url.Parse(match[1])
|
||||
if err != nil {
|
||||
errc <- fmt.Errorf("failed to parse API URL %q: %v", match[1], err)
|
||||
return
|
||||
}
|
||||
i.apiURL = u
|
||||
}
|
||||
if match := adminServerAddrRE.FindStringSubmatch(s.Text()); match != nil {
|
||||
i.adminURL = match[1]
|
||||
}
|
||||
if i.adminURL != "" && i.apiURL != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
errc <- s.Err()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-time.After(15 * time.Second):
|
||||
if p := i.child.Process; p != nil {
|
||||
p.Kill()
|
||||
}
|
||||
return errors.New("timeout starting child process")
|
||||
case err := <-errc:
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading child process stderr: %v", err)
|
||||
}
|
||||
}
|
||||
if i.adminURL == "" {
|
||||
return errors.New("unable to find admin server URL")
|
||||
}
|
||||
if i.apiURL == nil {
|
||||
return errors.New("unable to find API server URL")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *instance) appYAML() string {
|
||||
return fmt.Sprintf(appYAMLTemplate, i.appID)
|
||||
}
|
||||
|
||||
const appYAMLTemplate = `
|
||||
application: %s
|
||||
version: 1
|
||||
runtime: go
|
||||
api_version: go1
|
||||
vm: true
|
||||
|
||||
handlers:
|
||||
- url: /.*
|
||||
script: _go_app
|
||||
`
|
||||
|
||||
const appSource = `
|
||||
package main
|
||||
import "google.golang.org/appengine"
|
||||
func main() { appengine.Main() }
|
||||
`
|
36
vendor/google.golang.org/appengine/aetest/user.go
generated
vendored
Normal file
36
vendor/google.golang.org/appengine/aetest/user.go
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
package aetest
|
||||
|
||||
import (
|
||||
"hash/crc32"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"google.golang.org/appengine/user"
|
||||
)
|
||||
|
||||
// Login causes the provided Request to act as though issued by the given user.
|
||||
func Login(u *user.User, req *http.Request) {
|
||||
req.Header.Set("X-AppEngine-User-Email", u.Email)
|
||||
id := u.ID
|
||||
if id == "" {
|
||||
id = strconv.Itoa(int(crc32.Checksum([]byte(u.Email), crc32.IEEETable)))
|
||||
}
|
||||
req.Header.Set("X-AppEngine-User-Id", id)
|
||||
req.Header.Set("X-AppEngine-User-Federated-Identity", u.Email)
|
||||
req.Header.Set("X-AppEngine-User-Federated-Provider", u.FederatedProvider)
|
||||
if u.Admin {
|
||||
req.Header.Set("X-AppEngine-User-Is-Admin", "1")
|
||||
} else {
|
||||
req.Header.Set("X-AppEngine-User-Is-Admin", "0")
|
||||
}
|
||||
}
|
||||
|
||||
// Logout causes the provided Request to act as though issued by a logged-out
|
||||
// user.
|
||||
func Logout(req *http.Request) {
|
||||
req.Header.Del("X-AppEngine-User-Email")
|
||||
req.Header.Del("X-AppEngine-User-Id")
|
||||
req.Header.Del("X-AppEngine-User-Is-Admin")
|
||||
req.Header.Del("X-AppEngine-User-Federated-Identity")
|
||||
req.Header.Del("X-AppEngine-User-Federated-Provider")
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue