github.com/canthefason/helm@v2.2.1-0.20170221172616-16b043b8d505+incompatible/pkg/releasetesting/test_suite_test.go (about)

     1  /*
     2  Copyright 2016 The Kubernetes Authors All rights reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package releasetesting
    18  
    19  import (
    20  	"io"
    21  	"os"
    22  	"testing"
    23  	"time"
    24  
    25  	"github.com/golang/protobuf/ptypes/timestamp"
    26  	"golang.org/x/net/context"
    27  	grpc "google.golang.org/grpc"
    28  	"google.golang.org/grpc/metadata"
    29  	"k8s.io/kubernetes/pkg/api"
    30  
    31  	"k8s.io/helm/pkg/helm"
    32  	"k8s.io/helm/pkg/proto/hapi/chart"
    33  	"k8s.io/helm/pkg/proto/hapi/release"
    34  	"k8s.io/helm/pkg/proto/hapi/services"
    35  	"k8s.io/helm/pkg/storage"
    36  	"k8s.io/helm/pkg/storage/driver"
    37  	tillerEnv "k8s.io/helm/pkg/tiller/environment"
    38  )
    39  
    40  const manifestWithTestSuccessHook = `
    41  apiVersion: v1
    42  kind: Pod
    43  metadata:
    44    name: finding-nemo,
    45    annotations:
    46      "helm.sh/hook": test-success
    47  spec:
    48    containers:
    49    - name: nemo-test
    50      image: fake-image
    51      cmd: fake-command
    52  `
    53  
    54  const manifestWithTestFailureHook = `
    55  apiVersion: v1
    56  kind: Pod
    57  metadata:
    58    name: gold-rush,
    59    annotations:
    60      "helm.sh/hook": test-failure
    61  spec:
    62    containers:
    63    - name: gold-finding-test
    64      image: fake-gold-finding-image
    65      cmd: fake-gold-finding-command
    66  `
    67  const manifestWithInstallHooks = `apiVersion: v1
    68  kind: ConfigMap
    69  metadata:
    70    name: test-cm
    71    annotations:
    72      "helm.sh/hook": post-install,pre-delete
    73  data:
    74    name: value
    75  `
    76  
    77  func TestNewTestSuite(t *testing.T) {
    78  	rel := releaseStub()
    79  
    80  	_, err := NewTestSuite(rel)
    81  	if err != nil {
    82  		t.Errorf("%s", err)
    83  	}
    84  }
    85  
    86  func TestRun(t *testing.T) {
    87  
    88  	testManifests := []string{manifestWithTestSuccessHook, manifestWithTestFailureHook}
    89  	ts := testSuiteFixture(testManifests)
    90  	if err := ts.Run(testEnvFixture()); err != nil {
    91  		t.Errorf("%s", err)
    92  	}
    93  
    94  	if ts.StartedAt == nil {
    95  		t.Errorf("Expected StartedAt to not be nil. Got: %v", ts.StartedAt)
    96  	}
    97  
    98  	if ts.CompletedAt == nil {
    99  		t.Errorf("Expected CompletedAt to not be nil. Got: %v", ts.CompletedAt)
   100  	}
   101  
   102  	if len(ts.Results) != 2 {
   103  		t.Errorf("Expected 2 test result. Got %v", len(ts.Results))
   104  	}
   105  
   106  	result := ts.Results[0]
   107  	if result.StartedAt == nil {
   108  		t.Errorf("Expected test StartedAt to not be nil. Got: %v", result.StartedAt)
   109  	}
   110  
   111  	if result.CompletedAt == nil {
   112  		t.Errorf("Expected test CompletedAt to not be nil. Got: %v", result.CompletedAt)
   113  	}
   114  
   115  	if result.Name != "finding-nemo" {
   116  		t.Errorf("Expected test name to be finding-nemo. Got: %v", result.Name)
   117  	}
   118  
   119  	if result.Status != release.TestRun_SUCCESS {
   120  		t.Errorf("Expected test result to be successful, got: %v", result.Status)
   121  	}
   122  
   123  	result2 := ts.Results[1]
   124  	if result2.StartedAt == nil {
   125  		t.Errorf("Expected test StartedAt to not be nil. Got: %v", result2.StartedAt)
   126  	}
   127  
   128  	if result2.CompletedAt == nil {
   129  		t.Errorf("Expected test CompletedAt to not be nil. Got: %v", result2.CompletedAt)
   130  	}
   131  
   132  	if result2.Name != "gold-rush" {
   133  		t.Errorf("Expected test name to be gold-rush, Got: %v", result2.Name)
   134  	}
   135  
   136  	if result2.Status != release.TestRun_FAILURE {
   137  		t.Errorf("Expected test result to be successful, got: %v", result2.Status)
   138  	}
   139  
   140  }
   141  
   142  func TestRunSuccessWithTestFailureHook(t *testing.T) {
   143  	ts := testSuiteFixture([]string{manifestWithTestFailureHook})
   144  	env := testEnvFixture()
   145  	env.KubeClient = newPodFailedKubeClient()
   146  	if err := ts.Run(env); err != nil {
   147  		t.Errorf("%s", err)
   148  	}
   149  
   150  	if ts.StartedAt == nil {
   151  		t.Errorf("Expected StartedAt to not be nil. Got: %v", ts.StartedAt)
   152  	}
   153  
   154  	if ts.CompletedAt == nil {
   155  		t.Errorf("Expected CompletedAt to not be nil. Got: %v", ts.CompletedAt)
   156  	}
   157  
   158  	if len(ts.Results) != 1 {
   159  		t.Errorf("Expected 1 test result. Got %v", len(ts.Results))
   160  	}
   161  
   162  	result := ts.Results[0]
   163  	if result.StartedAt == nil {
   164  		t.Errorf("Expected test StartedAt to not be nil. Got: %v", result.StartedAt)
   165  	}
   166  
   167  	if result.CompletedAt == nil {
   168  		t.Errorf("Expected test CompletedAt to not be nil. Got: %v", result.CompletedAt)
   169  	}
   170  
   171  	if result.Name != "gold-rush" {
   172  		t.Errorf("Expected test name to be gold-rush, Got: %v", result.Name)
   173  	}
   174  
   175  	if result.Status != release.TestRun_SUCCESS {
   176  		t.Errorf("Expected test result to be successful, got: %v", result.Status)
   177  	}
   178  }
   179  
   180  func TestExtractTestManifestsFromHooks(t *testing.T) {
   181  	rel := releaseStub()
   182  	testManifests, err := extractTestManifestsFromHooks(rel.Hooks)
   183  	if err != nil {
   184  		t.Errorf("Expected no error, Got: %s", err)
   185  	}
   186  
   187  	if len(testManifests) != 1 {
   188  		t.Errorf("Expected 1 test manifest, Got: %v", len(testManifests))
   189  	}
   190  }
   191  
   192  func chartStub() *chart.Chart {
   193  	return &chart.Chart{
   194  		Metadata: &chart.Metadata{
   195  			Name: "nemo",
   196  		},
   197  		Templates: []*chart.Template{
   198  			{Name: "templates/hello", Data: []byte("hello: world")},
   199  			{Name: "templates/hooks", Data: []byte(manifestWithTestSuccessHook)},
   200  		},
   201  	}
   202  }
   203  
   204  func releaseStub() *release.Release {
   205  	date := timestamp.Timestamp{Seconds: 242085845, Nanos: 0}
   206  	return &release.Release{
   207  		Name: "lost-fish",
   208  		Info: &release.Info{
   209  			FirstDeployed: &date,
   210  			LastDeployed:  &date,
   211  			Status:        &release.Status{Code: release.Status_DEPLOYED},
   212  			Description:   "a release stub",
   213  		},
   214  		Chart:   chartStub(),
   215  		Config:  &chart.Config{Raw: `name: value`},
   216  		Version: 1,
   217  		Hooks: []*release.Hook{
   218  			{
   219  				Name:     "finding-nemo",
   220  				Kind:     "Pod",
   221  				Path:     "finding-nemo",
   222  				Manifest: manifestWithTestSuccessHook,
   223  				Events: []release.Hook_Event{
   224  					release.Hook_RELEASE_TEST_SUCCESS,
   225  				},
   226  			},
   227  			{
   228  				Name:     "test-cm",
   229  				Kind:     "ConfigMap",
   230  				Path:     "test-cm",
   231  				Manifest: manifestWithInstallHooks,
   232  				Events: []release.Hook_Event{
   233  					release.Hook_POST_INSTALL,
   234  					release.Hook_PRE_DELETE,
   235  				},
   236  			},
   237  		},
   238  	}
   239  }
   240  
   241  func testFixture() *test {
   242  	return &test{
   243  		manifest: manifestWithTestSuccessHook,
   244  		result:   &release.TestRun{},
   245  	}
   246  }
   247  
   248  func testSuiteFixture(testManifests []string) *TestSuite {
   249  	if len(testManifests) == 0 {
   250  		testManifests = []string{manifestWithTestSuccessHook, manifestWithTestFailureHook}
   251  	}
   252  	testResults := []*release.TestRun{}
   253  	ts := &TestSuite{
   254  		TestManifests: testManifests,
   255  		Results:       testResults,
   256  	}
   257  
   258  	return ts
   259  }
   260  
   261  func testEnvFixture() *Environment {
   262  	return newMockTestingEnvironment().Environment
   263  }
   264  
   265  func mockTillerEnvironment() *tillerEnv.Environment {
   266  	e := tillerEnv.New()
   267  	e.Releases = storage.Init(driver.NewMemory())
   268  	e.KubeClient = newPodSucceededKubeClient()
   269  	return e
   270  }
   271  
   272  type mockStream struct {
   273  	stream   grpc.ServerStream
   274  	messages []*services.TestReleaseResponse
   275  }
   276  
   277  func (rs mockStream) Send(m *services.TestReleaseResponse) error {
   278  	rs.messages = append(rs.messages, m)
   279  	return nil
   280  }
   281  func (rs mockStream) SetHeader(m metadata.MD) error  { return nil }
   282  func (rs mockStream) SendHeader(m metadata.MD) error { return nil }
   283  func (rs mockStream) SetTrailer(m metadata.MD)       {}
   284  func (rs mockStream) SendMsg(v interface{}) error    { return nil }
   285  func (rs mockStream) RecvMsg(v interface{}) error    { return nil }
   286  func (rs mockStream) Context() context.Context       { return helm.NewContext() }
   287  
   288  type podSucceededKubeClient struct {
   289  	tillerEnv.PrintingKubeClient
   290  }
   291  
   292  func newPodSucceededKubeClient() *podSucceededKubeClient {
   293  	return &podSucceededKubeClient{
   294  		PrintingKubeClient: tillerEnv.PrintingKubeClient{Out: os.Stdout},
   295  	}
   296  }
   297  
   298  func (p *podSucceededKubeClient) WaitAndGetCompletedPodPhase(ns string, r io.Reader, timeout time.Duration) (api.PodPhase, error) {
   299  	return api.PodSucceeded, nil
   300  }
   301  
   302  type podFailedKubeClient struct {
   303  	tillerEnv.PrintingKubeClient
   304  }
   305  
   306  func newPodFailedKubeClient() *podFailedKubeClient {
   307  	return &podFailedKubeClient{
   308  		PrintingKubeClient: tillerEnv.PrintingKubeClient{Out: os.Stdout},
   309  	}
   310  }
   311  
   312  func (p *podFailedKubeClient) WaitAndGetCompletedPodPhase(ns string, r io.Reader, timeout time.Duration) (api.PodPhase, error) {
   313  	return api.PodFailed, nil
   314  }