Skip to content

Commit

Permalink
Test in ci2 (#124)
Browse files Browse the repository at this point in the history
* basic test

* disable image pull check - larger timing issue

* enable download from vscode extension

* use ExpectWithOffset, option to download updates from vscode extension

* detect presence of dlv

* allow time for container to pull

* timeout tweaks

* better error messages for permissions

* use k8s error check
  • Loading branch information
mitchdraft authored Mar 8, 2019
1 parent 5878a67 commit 0bd4ecf
Show file tree
Hide file tree
Showing 9 changed files with 339 additions and 210 deletions.
3 changes: 3 additions & 0 deletions changelog/v0.5.1/cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
changelog:
- type: NON_USER_FACING
description: "basic e2e test"
19 changes: 15 additions & 4 deletions cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,35 @@ steps:
waitFor: ['get-creds']
id: 'check-code-and-docs-gen'

- name: 'gcr.io/$PROJECT_ID/e2e-ginkgo'
env:
- 'PROJECT_ROOT=github.com/solo-io/squash'
- 'GOPATH=/workspace/gopath'
- 'CLOUDSDK_COMPUTE_ZONE=us-central1-a'
- 'CLOUDSDK_CONTAINER_CLUSTER=test-cluster'
- 'RUN_KUBE_TESTS=1'
- 'DOCKER_CONFIG=/workspace/.docker/'
dir: './gopath/src/github.com/solo-io/squash'
args: ['-r', '-failFast', '-p']
waitFor: ['get-creds', 'check-code-and-docs-gen']
id: 'test'

- name: 'gcr.io/cloud-builders/docker'
entrypoint: 'bash'
args: ['-c', 'docker login quay.io --username "solo-io+solobot" --password $$QUAY_IO_PASSWORD']
secretEnv: ['QUAY_IO_PASSWORD']
id: 'docker-login'

- name: 'gcr.io/$PROJECT_ID/go-make'
args: ['docker']
args: ['-j', 'docker']
env:
- 'PROJECT_ROOT=github.com/solo-io/squash'
- 'GOPATH=/workspace/gopath'
- 'TAGGED_VERSION=$TAG_NAME'
- 'BUILD_ID=$BUILD_ID'
- 'GCLOUD_PROJECT_ID=$PROJECT_ID'
dir: './gopath/src/github.com/solo-io/squash'
waitFor: ['docker-login', 'check-code-and-docs-gen']
waitFor: ['test', 'docker-login', 'check-code-and-docs-gen']
id: 'compile'

- name: 'gcr.io/$PROJECT_ID/go-make'
Expand Down Expand Up @@ -104,5 +117,3 @@ secrets:
VSCODE_TOKEN: CiQABlzmSepRzBG6r2UapqKVaJfx5X3PQgWpuKtIinDWI4IpZsASXQCCPGSGtYjgB1ARs6VcRy3J23Mlbo7zeqPamti48qk71axnOBu4pSomCTKj+4iB81E/dgJEmo9aXOIfPoSv7jEs1ijN7J326jA+AOS1M4eUQwfAWovUtmjecP0p+Q==

timeout: 3000s
options:
machineType: 'N1_HIGHCPU_8'
23 changes: 15 additions & 8 deletions editor/vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,11 @@ async function getremote(extPath: string): Promise<string> {


// exit this early until release is smoothed out
return "";
if (fs.existsSync(execpath)) {
let exechash = await hash(execpath);
// make sure its the one we expect:
// this can happen on version updates.
if (exechash !== ks.checksum) {
if (!hashesMatch(ks.checksum, exechash)) {
// remove the bad binary.
fs.unlinkSync(execpath);
}
Expand All @@ -87,9 +86,7 @@ async function getremote(extPath: string): Promise<string> {
// test after the download
let exechash = await hash(execpath);
// make sure its the one we expect:
// first split because the github hash includes the filename
let hashParts = ks.checksum.split(" ");
if (hashParts.length != 2 || exechash !== hashParts[0]) {
if (!hashesMatch(ks.checksum, exechash)) {
// remove the bad binary.
fs.unlinkSync(execpath);
throw new Error("bad checksum for binary; download may be corrupted - please try again.");
Expand All @@ -114,6 +111,16 @@ function hash(f: string): Promise<string> {
});
}

// solo is the hash that was created from the squashctl binary when the binary was compiled
// gen is the hash that was generated locally from the squashctl file that the extension is trying to use
function hashesMatch(solo: string, gen: string): boolean {
let hashParts = solo.split(" ");
if (hashParts.length !== 2 || gen !== hashParts[0]) {
return false;
}
return true;
}

function download2file(what: string, to: string): Promise<any> {

return new Promise<any>((resolve, reject) => {
Expand Down Expand Up @@ -170,11 +177,11 @@ class SquashExtension {

async debug() {
let squashpath: string = get_conf_or("path", null);
console.log("using squashctl from:");
console.log(squashpath);
if (!squashpath) {
squashpath = await getremote(this.context.extensionPath);
}
console.log("using squashctl from:");
console.log(squashpath);

if (!vscode.workspace.workspaceFolders) {
throw new Error("no workspace folders");
Expand Down Expand Up @@ -469,7 +476,7 @@ interface SquashctlBinary {

function createSquashctlBinary(os: string, checksum: string): SquashctlBinary {
let link = "https://github.com/solo-io/squash/releases/download/" + getSquashInfo().version + "/" + getSquashInfo().baseName + "-" + os;
console.log("trying to dl from: " + link)
console.log("trying to dl from: " + link);
return {
link: "https://github.com/solo-io/squash/releases/download/" + getSquashInfo().version + "/" + getSquashInfo().baseName + "-" + os,
checksum: checksum
Expand Down
9 changes: 3 additions & 6 deletions pkg/config/squash.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,9 @@ func StartDebugContainer(s Squash, dbt DebugTarget) (*v1.Pod, error) {
}

// wait for running state
// ctx, cancel := context.WithTimeout(context.Background(), time.Duration(s.TimeoutSeconds)*time.Second)
ctx, cancel := context.WithTimeout(context.Background(), 6*time.Second)
ctx, cancel := context.WithTimeout(context.Background(), 300*time.Second)
err = <-s.waitForPod(ctx, createdPod)
cancel()
// ctx, cancel = context.WithTimeout(context.Background(), time.Duration(s.TimeoutSeconds)*time.Second)
// err <-s.waitForDebugAttachment(ctx)
if err != nil {
// s.printError(createdPodName)
return nil, fmt.Errorf("Waiting for pod: %v", err)
Expand Down Expand Up @@ -283,9 +280,9 @@ func (s *Squash) waitForPod(ctx context.Context, createdPod *v1.Pod) <-chan erro
if createdPod.Status.Phase != v1.PodPending {
// err := s.printError(createdPod)
if err != nil {
errchan <- errors.Wrap(err, "pod is not running and not pending")
errchan <- errors.Wrapf(err, "pod is not running and not pending, status: %v", createdPod.Status.Phase)
} else {
errchan <- errors.New("pod is not running and not pending")
errchan <- errors.New(fmt.Sprintf("pod is not running and not pending, status: %v", createdPod.Status.Phase))
}
return
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/debuggers/local/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func waitForDebugServerAddress(daName, daNamespace string) (*v1.DebugAttachment,
}

// TODO - make timeout configurable
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
ctx, cancel := context.WithTimeout(ctx, 300*time.Second)
defer cancel()
for {
select {
Expand Down
36 changes: 28 additions & 8 deletions pkg/squashctl/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"gopkg.in/AlecAivazis/survey.v1"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)
Expand Down Expand Up @@ -206,10 +207,11 @@ func (o *Options) createPlankPermissions() error {
// create namespace. ignore errors as it most likely exists and will error
cs.CoreV1().Namespaces().Create(&corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}})

_, err = cs.CoreV1().ServiceAccounts(namespace).Get(sqOpts.PlankServiceAccountName, metav1.GetOptions{})
if err == nil {
// service account already exists, no need to create it
return nil
if _, err := cs.CoreV1().ServiceAccounts(namespace).Get(sqOpts.PlankServiceAccountName, metav1.GetOptions{}); err != nil {
if !errors.IsAlreadyExists(err) {
// service account already exists, no need to create it
return err
}
}

sa := corev1.ServiceAccount{
Expand All @@ -218,9 +220,11 @@ func (o *Options) createPlankPermissions() error {
},
}

fmt.Printf("Creating service account %v in namespace %v\n", sqOpts.PlankServiceAccountName, namespace)
o.info(fmt.Sprintf("Creating service account %v in namespace %v\n", sqOpts.PlankServiceAccountName, namespace))
if _, err := cs.CoreV1().ServiceAccounts(namespace).Create(&sa); err != nil {
fmt.Println(err)
if !errors.IsAlreadyExists(err) {
return err
}
}

cr := &rbacv1.ClusterRole{
Expand Down Expand Up @@ -251,8 +255,11 @@ func (o *Options) createPlankPermissions() error {
},
},
}
o.info(fmt.Sprintf("Creating cluster role %v \n", sqOpts.PlankClusterRoleName))
if _, err := cs.Rbac().ClusterRoles().Create(cr); err != nil {
fmt.Println(err)
if !errors.IsAlreadyExists(err) {
return err
}
}

crb := &rbacv1.ClusterRoleBinding{
Expand All @@ -272,9 +279,14 @@ func (o *Options) createPlankPermissions() error {
Kind: "ClusterRole",
},
}

o.info(fmt.Sprintf("Creating cluster role binding %v \n", sqOpts.PlankClusterRoleBindingName))
if _, err := cs.Rbac().ClusterRoleBindings().Create(crb); err != nil {
fmt.Println(err)
if !errors.IsAlreadyExists(err) {
return err
}
}
o.info(fmt.Sprintf("All squashctl permission resources created.\n"))
return nil
}

Expand All @@ -285,3 +297,11 @@ func getClientSet() (kubernetes.Interface, error) {
}
return kubernetes.NewForConfig(restCfg)
}

// only print info if squashctl is being used by a human
// machine mode currently expects an exact output
func (o *Options) info(msg string) {
if !o.Squash.Machine {
fmt.Println(msg)
}
}
15 changes: 14 additions & 1 deletion test/e2e/e2e_suite_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package e2e_test

import (
"fmt"
"math/rand"
"time"

. "github.com/onsi/ginkgo"
"github.com/solo-io/solo-kit/test/helpers"
"github.com/solo-io/squash/test/testutils"

"testing"
)
Expand All @@ -12,5 +17,13 @@ func TestE2e(t *testing.T) {
helpers.RegisterCommonFailHandlers()
helpers.SetupLog()

RunSpecs(t, "E2e Suite")
RunSpecs(t, "E2e Squash Suite")
}

var _ = BeforeSuite(func() {
testutils.DeclareTestConditions()

seed := time.Now().UnixNano()
fmt.Printf("rand seed: %v\n", seed)
rand.Seed(seed)
})
Loading

0 comments on commit 0bd4ecf

Please sign in to comment.