github.com/shashidharatd/test-infra@v0.0.0-20171006011030-71304e1ca560/scenarios/kubernetes_e2e_test.py (about)

     1  #!/usr/bin/env python
     2  
     3  # Copyright 2017 The Kubernetes Authors.
     4  #
     5  # Licensed under the Apache License, Version 2.0 (the "License");
     6  # you may not use this file except in compliance with the License.
     7  # You may obtain a copy of the License at
     8  #
     9  #     http://www.apache.org/licenses/LICENSE-2.0
    10  #
    11  # Unless required by applicable law or agreed to in writing, software
    12  # distributed under the License is distributed on an "AS IS" BASIS,
    13  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  # See the License for the specific language governing permissions and
    15  # limitations under the License.
    16  
    17  # Need to figure out why this only fails on travis
    18  # pylint: disable=too-few-public-methods
    19  
    20  """Test for kubernetes_e2e.py"""
    21  
    22  import json
    23  import os
    24  import re
    25  import shutil
    26  import string
    27  import tempfile
    28  import urllib
    29  import urllib2
    30  import unittest
    31  import time
    32  
    33  import kubernetes_e2e
    34  
    35  FAKE_WORKSPACE_STATUS = 'STABLE_BUILD_GIT_COMMIT 599539dc0b99976fda0f326f4ce47e93ec07217c\n' \
    36  'STABLE_BUILD_SCM_STATUS clean\n' \
    37  'STABLE_BUILD_SCM_REVISION v1.7.0-alpha.0.1320+599539dc0b9997\n' \
    38  'STABLE_BUILD_MAJOR_VERSION 1\n' \
    39  'STABLE_BUILD_MINOR_VERSION 7+\n' \
    40  'STABLE_gitCommit 599539dc0b99976fda0f326f4ce47e93ec07217c\n' \
    41  'STABLE_gitTreeState clean\n' \
    42  'STABLE_gitVersion v1.7.0-alpha.0.1320+599539dc0b9997\n' \
    43  'STABLE_gitMajor 1\n' \
    44  'STABLE_gitMinor 7+\n'
    45  
    46  FAKE_WORKSPACE_STATUS_V1_6 = 'STABLE_BUILD_GIT_COMMIT 84febd4537dd190518657405b7bdb921dfbe0387\n' \
    47  'STABLE_BUILD_SCM_STATUS clean\n' \
    48  'STABLE_BUILD_SCM_REVISION v1.6.4-beta.0.18+84febd4537dd19\n' \
    49  'STABLE_BUILD_MAJOR_VERSION 1\n' \
    50  'STABLE_BUILD_MINOR_VERSION 6+\n' \
    51  'STABLE_gitCommit 84febd4537dd190518657405b7bdb921dfbe0387\n' \
    52  'STABLE_gitTreeState clean\n' \
    53  'STABLE_gitVersion v1.6.4-beta.0.18+84febd4537dd19\n' \
    54  'STABLE_gitMajor 1\n' \
    55  'STABLE_gitMinor 6+\n'
    56  
    57  FAKE_DESCRIBE_FROM_FAMILY_RESPONSE = """
    58  archiveSizeBytes: '1581831882'
    59  creationTimestamp: '2017-06-16T10:37:57.681-07:00'
    60  description: 'Google, Container-Optimized OS, 59-9460.64.0 stable, Kernel: ChromiumOS-4.4.52
    61    Kubernetes: 1.6.4 Docker: 1.11.2'
    62  diskSizeGb: '10'
    63  family: cos-stable
    64  id: '2388425242502080922'
    65  kind: compute#image
    66  labelFingerprint: 42WmSpB8rSM=
    67  licenses:
    68  - https://www.googleapis.com/compute/v1/projects/cos-cloud/global/licenses/cos
    69  name: cos-stable-59-9460-64-0
    70  rawDisk:
    71    containerType: TAR
    72    source: ''
    73  selfLink: https://www.googleapis.com/compute/v1/projects/cos-cloud/global/images/cos-stable-59-9460-64-0
    74  sourceType: RAW
    75  status: READY
    76  """
    77  
    78  def fake_pass(*_unused, **_unused2):
    79      """Do nothing."""
    80      pass
    81  
    82  def fake_bomb(*a, **kw):
    83      """Always raise."""
    84      raise AssertionError('Should not happen', a, kw)
    85  
    86  def raise_urllib2_error(*_unused, **_unused2):
    87      """Always raise a urllib2.URLError"""
    88      raise urllib2.URLError("test failure")
    89  
    90  def always_kubernetes(*_unused, **_unused2):
    91      """Always return 'kubernetes'"""
    92      return 'kubernetes'
    93  
    94  class Stub(object):
    95      """Replace thing.param with replacement until exiting with."""
    96      def __init__(self, thing, param, replacement):
    97          self.thing = thing
    98          self.param = param
    99          self.replacement = replacement
   100          self.old = getattr(thing, param)
   101          setattr(thing, param, self.replacement)
   102  
   103      def __enter__(self, *a, **kw):
   104          return self.replacement
   105  
   106      def __exit__(self, *a, **kw):
   107          setattr(self.thing, self.param, self.old)
   108  
   109  
   110  class ClusterNameTest(unittest.TestCase):
   111      def test_name_filled(self):
   112          """Return the cluster name if set."""
   113          name = 'foo'
   114          build = '1984'
   115          actual = kubernetes_e2e.cluster_name(name, build)
   116          self.assertTrue(actual)
   117          self.assertIn(name, actual)
   118          self.assertNotIn(build, actual)
   119  
   120      def test_name_empty_short_build(self):
   121          """Return the build number if name is empty."""
   122          name = ''
   123          build = '1984'
   124          actual = kubernetes_e2e.cluster_name(name, build)
   125          self.assertTrue(actual)
   126          self.assertIn(build, actual)
   127  
   128      def test_name_empty_long_build(self):
   129          """Return a short hash of a long build number if name is empty."""
   130          name = ''
   131          build = '0' * 63
   132          actual = kubernetes_e2e.cluster_name(name, build)
   133          self.assertTrue(actual)
   134          self.assertNotIn(build, actual)
   135          if len(actual) > 32:  # Some firewall names consume half the quota
   136              self.fail('Name should be short: %s' % actual)
   137  
   138  
   139  class ScenarioTest(unittest.TestCase):  # pylint: disable=too-many-public-methods
   140      """Test for e2e scenario."""
   141      callstack = []
   142      envs = {}
   143  
   144      def setUp(self):
   145          self.boiler = [
   146              Stub(kubernetes_e2e, 'check', self.fake_check),
   147              Stub(shutil, 'copy', fake_pass),
   148          ]
   149  
   150      def tearDown(self):
   151          for stub in self.boiler:
   152              with stub:  # Leaving with restores things
   153                  pass
   154          self.callstack[:] = []
   155          self.envs.clear()
   156  
   157      def fake_check(self, *cmd):
   158          """Log the command."""
   159          self.callstack.append(string.join(cmd))
   160  
   161      def fake_check_env(self, env, *cmd):
   162          """Log the command with a specific env."""
   163          self.envs.update(env)
   164          self.callstack.append(string.join(cmd))
   165  
   166      def fake_output_work_status(self, *cmd):
   167          """fake a workstatus blob."""
   168          self.callstack.append(string.join(cmd))
   169          return FAKE_WORKSPACE_STATUS
   170  
   171      def fake_output_work_status_v1_6(self, *cmd):
   172          """fake a workstatus blob for v1.6."""
   173          self.callstack.append(string.join(cmd))
   174          return FAKE_WORKSPACE_STATUS_V1_6
   175  
   176      def fake_output_get_latest_image(self, *cmd):
   177          """fake a `gcloud compute images describe-from-family` response."""
   178          self.callstack.append(string.join(cmd))
   179          return FAKE_DESCRIBE_FROM_FAMILY_RESPONSE
   180  
   181      def test_local(self):
   182          """Make sure local mode is fine overall."""
   183          args = kubernetes_e2e.parse_args()
   184          self.assertEqual(args.mode, 'local')
   185          with Stub(kubernetes_e2e, 'check_env', self.fake_check_env):
   186              kubernetes_e2e.main(args)
   187  
   188          self.assertNotEqual(self.envs, {})
   189          for call in self.callstack:
   190              self.assertFalse(call.startswith('docker'))
   191  
   192      def test_check_leaks(self):
   193          """Ensure --check-leaked-resources=true sends flag to kubetest."""
   194          args = kubernetes_e2e.parse_args(['--check-leaked-resources=true'])
   195          with Stub(kubernetes_e2e, 'check_env', self.fake_check_env):
   196              kubernetes_e2e.main(args)
   197              self.assertIn('--check-leaked-resources=true', self.callstack[-1])
   198  
   199      def test_check_leaks_false(self):
   200          """Ensure --check-leaked-resources=true sends flag to kubetest."""
   201          args = kubernetes_e2e.parse_args(['--check-leaked-resources=false'])
   202          with Stub(kubernetes_e2e, 'check_env', self.fake_check_env):
   203              kubernetes_e2e.main(args)
   204              self.assertIn('--check-leaked-resources=false', self.callstack[-1])
   205  
   206      def test_check_leaks_default(self):
   207          """Ensure --check-leaked-resources=true sends flag to kubetest."""
   208          args = kubernetes_e2e.parse_args(['--check-leaked-resources'])
   209          with Stub(kubernetes_e2e, 'check_env', self.fake_check_env):
   210              kubernetes_e2e.main(args)
   211              self.assertIn('--check-leaked-resources', self.callstack[-1])
   212  
   213      def test_check_leaks_unset(self):
   214          """Ensure --check-leaked-resources=true sends flag to kubetest."""
   215          args = kubernetes_e2e.parse_args(['--mode=local'])
   216          with Stub(kubernetes_e2e, 'check_env', self.fake_check_env):
   217              kubernetes_e2e.main(args)
   218              self.assertNotIn('--check-leaked-resources', self.callstack[-1])
   219  
   220      def test_migrated_kubetest_args(self):
   221          migrated = [
   222              '--stage-suffix=panda',
   223              '--random-flag', 'random-value',
   224              '--multiple-federations',
   225              'arg1', 'arg2',
   226              '--federation',
   227              '--kubemark',
   228              '--extract=this',
   229              '--extract=that',
   230              '--perf-tests',
   231              '--deployment=yay',
   232              '--save=somewhere',
   233              '--skew',
   234              '--publish=location',
   235              '--timeout=42m',
   236              '--upgrade_args=ginkgo',
   237              '--check-leaked-resources=true',
   238              '--charts',
   239          ]
   240          args = kubernetes_e2e.parse_args(['--mode=docker'] + migrated + ['--test=false'])
   241          self.assertEquals(migrated, args.kubetest_args)
   242          with Stub(kubernetes_e2e, 'check_env', self.fake_check_env):
   243              kubernetes_e2e.main(args)
   244          lastcall = self.callstack[-2]
   245          for arg in migrated:
   246              self.assertIn(arg, lastcall)
   247  
   248      def test_updown_default(self):
   249          args = kubernetes_e2e.parse_args(['--mode=local'])
   250          with Stub(kubernetes_e2e, 'check_env', self.fake_check_env):
   251              kubernetes_e2e.main(args)
   252          lastcall = self.callstack[-1]
   253          self.assertIn('--up', lastcall)
   254          self.assertIn('--down', lastcall)
   255  
   256      def test_updown_set(self):
   257          args = kubernetes_e2e.parse_args(['--mode=local', '--up=false', '--down=true'])
   258          with Stub(kubernetes_e2e, 'check_env', self.fake_check_env):
   259              kubernetes_e2e.main(args)
   260          lastcall = self.callstack[-1]
   261          self.assertNotIn('--up', lastcall)
   262          self.assertIn('--down', lastcall)
   263  
   264  
   265      def test_kubeadm_ci(self):
   266          """Make sure kubeadm ci mode is fine overall."""
   267          args = kubernetes_e2e.parse_args(['--mode=local', '--kubeadm=ci'])
   268          self.assertEqual(args.mode, 'local')
   269          self.assertEqual(args.kubeadm, 'ci')
   270          with Stub(kubernetes_e2e, 'check_env', self.fake_check_env):
   271              with Stub(kubernetes_e2e, 'check_output', self.fake_output_work_status):
   272                  kubernetes_e2e.main(args)
   273  
   274          self.assertNotIn('E2E_OPT', self.envs)
   275          version = 'gs://kubernetes-release-dev/bazel/v1.7.0-alpha.0.1320+599539dc0b9997/bin/linux/amd64/'  # pylint: disable=line-too-long
   276          self.assertIn('--kubernetes-anywhere-kubeadm-version=%s' % version, self.callstack[-1])
   277          called = False
   278          for call in self.callstack:
   279              self.assertFalse(call.startswith('docker'))
   280              if call == 'hack/print-workspace-status.sh':
   281                  called = True
   282          self.assertTrue(called)
   283  
   284      def test_local_env(self):
   285          """
   286              Ensure that host variables (such as GOPATH) are included,
   287              and added envs/env files overwrite os environment.
   288          """
   289          mode = kubernetes_e2e.LocalMode('/orig-workspace', '/random-artifacts')
   290          mode.add_environment(*(
   291              'FOO=BAR', 'GOPATH=/go/path', 'WORKSPACE=/new/workspace'))
   292          mode.add_os_environment(*('USER=jenkins', 'FOO=BAZ', 'GOOS=linux'))
   293          with tempfile.NamedTemporaryFile() as temp:
   294              temp.write('USER=prow')
   295              temp.flush()
   296              mode.add_file(temp.name)
   297          with Stub(kubernetes_e2e, 'check_env', self.fake_check_env):
   298              mode.start([])
   299          self.assertIn(('FOO', 'BAR'), self.envs.viewitems())
   300          self.assertIn(('WORKSPACE', '/new/workspace'), self.envs.viewitems())
   301          self.assertIn(('GOPATH', '/go/path'), self.envs.viewitems())
   302          self.assertIn(('USER', 'prow'), self.envs.viewitems())
   303          self.assertIn(('GOOS', 'linux'), self.envs.viewitems())
   304          self.assertNotIn(('USER', 'jenkins'), self.envs.viewitems())
   305          self.assertNotIn(('FOO', 'BAZ'), self.envs.viewitems())
   306  
   307      def test_kubeadm_periodic(self):
   308          """Make sure kubeadm periodic mode is fine overall."""
   309          args = kubernetes_e2e.parse_args(['--mode=local', '--kubeadm=periodic'])
   310          self.assertEqual(args.mode, 'local')
   311          self.assertEqual(args.kubeadm, 'periodic')
   312          with Stub(kubernetes_e2e, 'check_env', self.fake_check_env):
   313              with Stub(kubernetes_e2e, 'check_output', self.fake_output_work_status):
   314                  kubernetes_e2e.main(args)
   315  
   316          self.assertNotIn('E2E_OPT', self.envs)
   317          version = 'gs://kubernetes-release-dev/bazel/v1.7.0-alpha.0.1320+599539dc0b9997/bin/linux/amd64/'  # pylint: disable=line-too-long
   318          self.assertIn('--kubernetes-anywhere-kubeadm-version=%s' % version, self.callstack[-1])
   319          called = False
   320          for call in self.callstack:
   321              self.assertFalse(call.startswith('docker'))
   322              if call == 'hack/print-workspace-status.sh':
   323                  called = True
   324          self.assertTrue(called)
   325  
   326      def test_kubeadm_periodic_v1_6(self):
   327          """Make sure kubeadm periodic mode has correct version on v1.6"""
   328          args = kubernetes_e2e.parse_args(['--mode=local', '--kubeadm=periodic'])
   329          self.assertEqual(args.mode, 'local')
   330          self.assertEqual(args.kubeadm, 'periodic')
   331          with Stub(kubernetes_e2e, 'check_env', self.fake_check_env):
   332              with Stub(kubernetes_e2e, 'check_output', self.fake_output_work_status_v1_6):
   333                  kubernetes_e2e.main(args)
   334  
   335          self.assertNotIn('E2E_OPT', self.envs)
   336          version = 'gs://kubernetes-release-dev/bazel/v1.6.4-beta.0.18+84febd4537dd19/build/debs/'
   337          self.assertIn('--kubernetes-anywhere-kubeadm-version=%s' % version, self.callstack[-1])
   338          called = False
   339          for call in self.callstack:
   340              self.assertFalse(call.startswith('docker'))
   341              if call == 'hack/print-workspace-status.sh':
   342                  called = True
   343          self.assertTrue(called)
   344  
   345      def test_kubeadm_pull(self):
   346          """Make sure kubeadm pull mode is fine overall."""
   347          args = kubernetes_e2e.parse_args([
   348              '--mode=local',
   349              '--kubeadm=pull',
   350              '--use-shared-build=bazel'
   351          ])
   352          self.assertEqual(args.mode, 'local')
   353          self.assertEqual(args.kubeadm, 'pull')
   354          self.assertEqual(args.use_shared_build, 'bazel')
   355  
   356          gcs_bucket = "gs://kubernetes-release-dev/bazel/v1.8.0-beta.1.132+599539dc0b9997"
   357  
   358          def fake_gcs_path(path):
   359              bazel_default = os.path.join(
   360                  'gs://kubernetes-jenkins/shared-results', 'bazel-build-location.txt')
   361              self.assertEqual(path, bazel_default)
   362              return gcs_bucket
   363          with Stub(kubernetes_e2e, 'check_env', self.fake_check_env):
   364              with Stub(kubernetes_e2e, 'read_gcs_path', fake_gcs_path):
   365                  kubernetes_e2e.main(args)
   366  
   367          self.assertNotIn('E2E_OPT', self.envs)
   368          version = '%s/bin/linux/amd64/' % gcs_bucket
   369          self.assertIn('--kubernetes-anywhere-kubeadm-version=%s' % version, self.callstack[-1])
   370  
   371      def test_kubeadm_invalid(self):
   372          """Make sure kubeadm invalid mode exits unsuccessfully."""
   373          with self.assertRaises(SystemExit) as sysexit:
   374              kubernetes_e2e.parse_args(['--mode=local', '--kubeadm=deploy'])
   375  
   376          self.assertEqual(sysexit.exception.code, 2)
   377  
   378      def test_docker(self):
   379          """Make sure docker mode is fine overall."""
   380          args = kubernetes_e2e.parse_args(['--mode=docker'])
   381          self.assertEqual(args.mode, 'docker')
   382          with Stub(kubernetes_e2e, 'check_env', fake_bomb):
   383              kubernetes_e2e.main(args)
   384  
   385          self.assertEqual(self.envs, {})
   386          call = self.callstack[-2]
   387          self.assertTrue(call.startswith('docker'), call)
   388  
   389      def test_default_tag(self):
   390          """Ensure the default tag exists on gcr.io."""
   391          args = kubernetes_e2e.parse_args()
   392          match = re.match('gcr.io/([^:]+):(.+)', kubernetes_e2e.kubekins(args.tag))
   393          self.assertIsNotNone(match)
   394          url = 'https://gcr.io/v2/%s/manifests/%s' % (match.group(1),
   395                                                       match.group(2))
   396          data = json.loads(urllib.urlopen(url).read())
   397          self.assertNotIn('errors', data)
   398          self.assertIn('name', data)
   399  
   400      def test_docker_env(self):
   401          """
   402              Ensure that host variables (such as GOPATH) are excluded,
   403              and OS envs are included.
   404          """
   405          mode = kubernetes_e2e.DockerMode(
   406              'fake-container', '/host-workspace', False, 'fake-tag', [])
   407          mode.add_environment(*('FOO=BAR', 'GOPATH=/something/else',
   408                                 'WORKSPACE=/new/workspace'))
   409          mode.add_os_environment('USER=jenkins')
   410          self.assertIn('FOO=BAR', mode.cmd)
   411          self.assertIn('WORKSPACE=/workspace', mode.cmd)
   412          self.assertNotIn('GOPATH=/something/else', mode.cmd)
   413          self.assertIn('USER=jenkins', mode.cmd)
   414  
   415      def test_image_family(self):
   416          """Make sure --image-family fetches the latest image correctly."""
   417          args = kubernetes_e2e.parse_args([
   418              '--mode=local',
   419              '--image-family=cos-stable',
   420              '--image-project=cos-cloud'])
   421          with Stub(kubernetes_e2e, 'check_env', self.fake_check_env):
   422              with Stub(
   423                  kubernetes_e2e,
   424                  'check_output',
   425                  self.fake_output_get_latest_image):
   426                  kubernetes_e2e.main(args)
   427          self.assertEqual(
   428              self.envs['KUBE_GCE_NODE_IMAGE'], 'cos-stable-59-9460-64-0')
   429          self.assertEqual(self.envs['KUBE_GCE_NODE_PROJECT'], 'cos-cloud')
   430  
   431      def test_parse_args_order_agnostic(self):
   432          args = kubernetes_e2e.parse_args([
   433              '--mode=local',
   434              '--some-kubetest-arg=foo',
   435              '--cluster=test'])
   436          self.assertEqual(args.kubetest_args, ['--some-kubetest-arg=foo'])
   437          self.assertEqual(args.mode, 'local')
   438          self.assertEqual(args.cluster, 'test')
   439  
   440      def test_gcp_network(self):
   441          args = kubernetes_e2e.parse_args(['--mode=local', '--cluster=test'])
   442          with Stub(kubernetes_e2e, 'check_env', self.fake_check_env):
   443              kubernetes_e2e.main(args)
   444          lastcall = self.callstack[-1]
   445          self.assertIn('--gcp-network=test', lastcall)
   446  
   447      def test_env_local(self):
   448          env = 'FOO'
   449          value = 'BLAT'
   450          args = kubernetes_e2e.parse_args([
   451              '--mode=local',
   452              '--env={env}={value}'.format(env=env, value=value),
   453          ])
   454          with Stub(kubernetes_e2e, 'check_env', self.fake_check_env):
   455              kubernetes_e2e.main(args)
   456          self.assertIn(env, self.envs)
   457          self.assertEqual(self.envs[env], value)
   458  
   459      def test_env_docker(self):
   460          env = 'FOO=bar blatz'
   461          args = kubernetes_e2e.parse_args([
   462              '--mode=docker',
   463              '--env=' + env,
   464          ])
   465          kubernetes_e2e.main(args)
   466          self.assertIn('-e '+env, self.callstack[-2])
   467  
   468      def test_aws(self):
   469          temp = tempfile.NamedTemporaryFile()
   470          args = kubernetes_e2e.parse_args([
   471              '--aws',
   472              '--cluster=foo',
   473              '--aws-cluster-domain=test-aws.k8s.io',
   474              '--aws-ssh=%s' % temp.name,
   475              '--aws-pub=%s' % temp.name,
   476              '--aws-cred=%s' % temp.name,
   477              ])
   478          with Stub(kubernetes_e2e, 'check_env', self.fake_check_env):
   479              kubernetes_e2e.main(args)
   480  
   481          lastcall = self.callstack[-1]
   482          self.assertIn('kops-e2e-runner.sh', lastcall)
   483          self.assertIn('--kops-cluster=foo.test-aws.k8s.io', lastcall)
   484          self.assertIn('--kops-zones', lastcall)
   485          self.assertIn('--kops-state=s3://k8s-kops-jenkins/', lastcall)
   486          self.assertIn('--kops-nodes=4', lastcall)
   487          self.assertIn('--kops-ssh-key', lastcall)
   488  
   489          self.assertEqual(
   490              self.envs['JENKINS_AWS_SSH_PRIVATE_KEY_FILE'], temp.name)
   491          self.assertEqual(
   492              self.envs['JENKINS_AWS_SSH_PUBLIC_KEY_FILE'], temp.name)
   493          self.assertEqual(
   494              self.envs['JENKINS_AWS_CREDENTIALS_FILE'], temp.name)
   495  
   496      def test_use_shared_build(self):
   497          # normal path
   498          args = kubernetes_e2e.parse_args([
   499              '--use-shared-build=bazel'
   500          ])
   501          def expect_bazel_gcs(path):
   502              bazel_default = os.path.join(
   503                  'gs://kubernetes-jenkins/shared-results', 'bazel-build-location.txt')
   504              self.assertEqual(path, bazel_default)
   505              return always_kubernetes()
   506          with Stub(kubernetes_e2e, 'check_env', self.fake_check_env):
   507              with Stub(kubernetes_e2e, 'read_gcs_path', expect_bazel_gcs):
   508                  with Stub(time, 'sleep', fake_pass):
   509                      kubernetes_e2e.main(args)
   510          lastcall = self.callstack[-1]
   511          self.assertIn('--extract=kubernetes', lastcall)
   512          # normal path, not bazel
   513          args = kubernetes_e2e.parse_args([
   514              '--use-shared-build'
   515          ])
   516          def expect_normal_gcs(path):
   517              bazel_default = os.path.join(
   518                  'gs://kubernetes-jenkins/shared-results', 'build-location.txt')
   519              self.assertEqual(path, bazel_default)
   520              return always_kubernetes()
   521          with Stub(kubernetes_e2e, 'check_env', self.fake_check_env):
   522              with Stub(kubernetes_e2e, 'read_gcs_path', expect_normal_gcs):
   523                  kubernetes_e2e.main(args)
   524          lastcall = self.callstack[-1]
   525          self.assertIn('--extract=kubernetes', lastcall)
   526          # test failure to read shared path from GCS
   527          with Stub(kubernetes_e2e, 'check_env', self.fake_check_env):
   528              with Stub(kubernetes_e2e, 'read_gcs_path', raise_urllib2_error):
   529                  with Stub(os, 'getcwd', always_kubernetes):
   530                      with Stub(time, 'sleep', fake_pass):
   531                          try:
   532                              kubernetes_e2e.main(args)
   533                          except RuntimeError as err:
   534                              if not err.message.startswith('Failed to get shared build location'):
   535                                  raise err
   536  
   537  if __name__ == '__main__':
   538      unittest.main()