Skip to content

Commit

Permalink
feat: basic lifecycle integraiton tests
Browse files Browse the repository at this point in the history
  • Loading branch information
lkingland committed Mar 10, 2021
1 parent 4f2f577 commit 8edd0df
Showing 1 changed file with 225 additions and 2 deletions.
227 changes: 225 additions & 2 deletions client_int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@
package function_test

import (
"os"
"reflect"
"testing"
"time"

boson "github.com/boson-project/func"
"github.com/boson-project/func/buildpacks"
"github.com/boson-project/func/docker"
"github.com/boson-project/func/knative"
"testing"
)

/*
Expand Down Expand Up @@ -35,7 +41,16 @@ import (
./hack/delete.sh
*/

const DefaultNamespace = "func"
const (
// DefaultRegistry must contain both the registry host and
// registry namespace at this time. This will likely be
// split and defaulted to the forthcoming in-cluster registry.
DefaultRegistry = "localhost:5000/func"

// DefaultNamespace for the underlying deployments. Must be the same
// as is set up and configured (see hack/configure.sh)
DefaultNamespace = "func"
)

func TestList(t *testing.T) {
verbose := true
Expand All @@ -60,3 +75,211 @@ func TestList(t *testing.T) {
t.Fatalf("Expected no Functions, got %v", names)
}
}

// TestNew creates
func TestNew(t *testing.T) {
defer within(t, "testdata/example.com/testnew")()
verbose := true

client := newClient(verbose)

// Act
if err := client.New(boson.Function{Name: "testnew", Root: ".", Runtime: "go"}); err != nil {
t.Fatal(err)
}
defer del(t, client, "testnew")

// Assert
names, err := client.List()
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(names, []string{"testnew"}) {
t.Fatalf("Expected function list ['testnew'], got %v", names)
}
}

// TestDeploy updates
func TestDeploy(t *testing.T) {
defer within(t, "testdata/example.com/deploy")()
verbose := true

client := newClient(verbose)

if err := client.New(boson.Function{Name: "deploy", Root: ".", Runtime: "go"}); err != nil {
t.Fatal(err)
}
defer del(t, client, "deploy")

if err := client.Deploy("."); err != nil {
t.Fatal(err)
}
}

// TestRemove deletes
func TestRemove(t *testing.T) {
defer within(t, "testdata/example.com/remove")()
verbose := true

client := newClient(verbose)

if err := client.New(boson.Function{Name: "remove", Root: ".", Runtime: "go"}); err != nil {
t.Fatal(err)
}
waitFor(t, client, "remove")

if err := client.Remove(boson.Function{Name: "remove"}); err != nil {
t.Fatal(err)
}

names, err := client.List()
if err != nil {
t.Fatal(err)
}
if len(names) != 0 {
t.Fatalf("Expected empty Functions list, got %v", names)
}
}

// ***********
// Helpers
// ***********

// newClient creates an instance of the func client whose concrete impls
// match those created by the kn func plugin CLI.
func newClient(verbose bool) *boson.Client {
builder := buildpacks.NewBuilder()
builder.Verbose = verbose

pusher := docker.NewPusher()
pusher.Verbose = verbose

deployer, err := knative.NewDeployer(DefaultNamespace)
if err != nil {
panic(err) // TODO: remove error from deployer constructor
}
deployer.Verbose = verbose

remover, err := knative.NewRemover(DefaultNamespace)
if err != nil {
panic(err) // TODO: remove error from remover constructor
}
remover.Verbose = verbose

lister, err := knative.NewLister(DefaultNamespace)
if err != nil {
panic(err) // TODO: remove error from lister constructor
}
lister.Verbose = verbose

return boson.New(
boson.WithRegistry(DefaultRegistry),
boson.WithVerbose(verbose),
boson.WithBuilder(builder),
boson.WithPusher(pusher),
boson.WithDeployer(deployer),
boson.WithRemover(remover),
boson.WithLister(lister),
)
}

// Del cleans up after a test by removing a function by name.
// (test fails if the named function does not exist)
//
// Intended to be run in a defer statement immediately after creation, del
// works around the asynchronicity of the underlying platform's creation
// step by polling the provider until the names function becomes available
// (or the test times out), before firing off a deletion request.
// Of course, ideally this would be replaced by the use of a synchronous
// method, or at a minimum a way to register a callback/listener for the
// creation event. This is what we have for now, and the show must go on.
func del(t *testing.T, c *boson.Client, name string) {
t.Helper()
waitFor(t, c, name)
if err := c.Remove(boson.Function{Name: name}); err != nil {
t.Fatal(err)
}
}

// waitFor the named Function to become available in List output.
// TODO: the API should be synchronous, but that depends first on
// Create returning the derived name such that we can bake polling in.
// Ideally the Boson provider's Creaet would be made syncrhonous.
func waitFor(t *testing.T, c *boson.Client, name string) {
t.Helper()
var pollInterval = 2 * time.Second

for { // ever (i.e. defer to global test timeout)
nn, err := c.List()
if err != nil {
t.Fatal(err)
}
for _, n := range nn {
if n.Name == name {
return
}
}
time.Sleep(pollInterval)
}
}

// Create the given directory, CD to it, and return a function which can be
// run in a defer statement to return to the original directory and cleanup.
// Note must be executed, not deferred itself
// NO: defer within(t, "somedir")
// YES: defer within(t, "somedir")()
func within(t *testing.T, root string) func() {
t.Helper()
cwd := pwd(t)
mkdir(t, root)
cd(t, root)
return func() {
cd(t, cwd)
rm(t, root)
}
}

func pwd(t *testing.T) string {
t.Helper()
dir, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
return dir
}

func mkdir(t *testing.T, dir string) {
t.Helper()
if err := os.MkdirAll(dir, 0700); err != nil {
t.Fatal(err)
}
}

func cd(t *testing.T, dir string) {
t.Helper()
if err := os.Chdir(dir); err != nil {
t.Fatal(err)
}
}

func rm(t *testing.T, dir string) {
t.Helper()
if err := os.RemoveAll(dir); err != nil {
t.Fatal(err)
}
}

func touch(file string) {
_, err := os.Stat(file)
if os.IsNotExist(err) {
f, err := os.Create(file)
if err != nil {
panic(err)
}
defer f.Close()
}
t := time.Now().Local()
if err := os.Chtimes(file, t, t); err != nil {
panic(err)
}
}

0 comments on commit 8edd0df

Please sign in to comment.