github.com/cilium/cilium@v1.16.2/Documentation/contributing/testing/e2e_legacy.rst (about)

     1  .. only:: not (epub or latex or html)
     2  
     3      WARNING: You are looking at unreleased Cilium documentation.
     4      Please use the official rendered version released here:
     5      https://docs.cilium.io
     6  
     7  .. _testsuite-legacy:
     8  
     9  End-To-End Testing Framework (Legacy)
    10  =====================================
    11  
    12  .. warning::
    13     The Ginkgo end-to-end testing framework is deprecated. New end-to-end
    14     tests should be implemented using the `cilium-cli
    15     <https://github.com/cilium/cilium-cli/#connectivity-check>`_ connectivity
    16     testing framework. For more information, see :ref:`testsuite`.
    17  
    18  Introduction
    19  ~~~~~~~~~~~~
    20  
    21  This section provides an overview of the two modes available for running
    22  Cilium's end-to-end tests locally: Vagrant and similar to GitHub Actions (GHA).
    23  It offers instructions on setting up and running tests in these modes.
    24  
    25  Before proceeding, it is recommended to familiarize yourself with Ginkgo by
    26  reading the `Ginkgo Getting-Started Guide
    27  <https://onsi.github.io/ginkgo/#getting-started>`_. You
    28  can also run the `example tests
    29  <https://github.com/onsi/composition-ginkgo-example>`_ to get a feel for the
    30  Ginkgo workflow.
    31  
    32  The tests in the ``test`` directory are built on top of Ginkgo and utilize the
    33  Ginkgo ``focus`` concept to determine which virtual machines (VMs), in ``vagrant``
    34  mode are necessary to run specific tests. All test names must begin with one of
    35  the following prefixes:
    36  
    37  - ``Runtime``: Tests Cilium in a runtime environment running on a single node.
    38  - ``K8s``: Sets up a small multi-node Kubernetes environment for testing features
    39    beyond a single host and Kubernetes-specific functionalities.
    40  
    41  
    42  Running Tests with GitHub Actions (GHA)
    43  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    44  
    45  GitHub Actions provide an alternative mode for running Cilium's end-to-end tests.
    46  The configuration is set up to closely match the environment used in GHA. Refer
    47  to the relevant documentation for instructions on running tests using GHA.
    48  
    49  Running Tests with Vagrant
    50  ^^^^^^^^^^^^^^^^^^^^^^^^^^
    51  
    52  To run tests locally using Vagrant, the test scripts invoke ``vagrant`` to create
    53  virtual machine(s). These tests utilize the Ginkgo testing framework, leveraging
    54  its rich capabilities and the benefits of Go's compilation-time checks and
    55  strong typing.
    56  
    57  Running End-To-End Tests
    58  ~~~~~~~~~~~~~~~~~~~~~~~~
    59  
    60  Running Locally Ginkgo Tests based on Ginkgo's GitHub Workflow
    61  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    62  
    63  Although it is not possible to run ``conformance-ginkgo.yaml`` or
    64  ``conformance-runtime.yaml`` locally, it is possible to setup an environment
    65  similar to the one used on GitHub.
    66  
    67  The following example will provide the steps to run one of the tests of the
    68  focus ``f09-datapath-misc-2`` on Kubernetes ``1.27`` with the kernel ``net-next``
    69  for the commit SHA ``7b368923823e63c9824ea2b5ee4dc026bc4d5cd8``.
    70  
    71  You can also perform these steps automatically using the script
    72  ``contrib/scripts/run-gh-ginkgo-workflow.sh``. Run this script with ``-h`` for
    73  usage information.
    74  
    75  #. Download dependencies locally (``helm``, ``ginkgo``).
    76  
    77     For ``helm``, the instructions can be found `here <https://helm.sh/docs/intro/install/>`_
    78  
    79     .. code-block:: shell-session
    80  
    81        $ HELM_VERSION=3.7.0
    82        $ wget "https://get.helm.sh/helm-v${HELM_VERSION}-linux-amd64.tar.gz"
    83        $ tar -xf "helm-v${HELM_VERSION}-linux-amd64.tar.gz"
    84        $ mv linux-amd64/helm ./helm
    85  
    86     Store these dependencies under a specific directory that will be used to run
    87     Qemu in the next steps.
    88  
    89     For ``ginkgo``, we will be using the same version used on GitHub action:
    90  
    91     .. code-block:: shell-session
    92  
    93        $ cd ~/
    94        $ go install github.com/onsi/ginkgo/ginkgo@v1.16.5
    95        $ ${GOPATH}/bin/ginkgo version
    96        Ginkgo Version 1.16.5
    97  
    98  #. Build the Ginkgo tests locally. This will create a binary named ``test.test``
    99     which we can use later on to run our tests.
   100  
   101     .. code-block:: shell-session
   102  
   103        $ cd github.com/cilium/cilium/test
   104        $ ${GOPATH}/bin/ginkgo build
   105  
   106  #. Provision VMs using Qemu:
   107  
   108     * Retrieve the image tag for the k8s and kernel versions that will be used for
   109       testing by checking the file ``.github/actions/ginkgo/main-k8s-versions.yaml``.
   110  
   111       For example:
   112  
   113          - kernel: ``bpf-next-20230526.105339@sha256:4133d4e09b1e86ac175df8d899873180281bb4220dc43e2566c47b0241637411``
   114          - k8s: ``kindest/node:v1.27.1@sha256:b7d12ed662b873bd8510879c1846e87c7e676a79fefc93e17b2a52989d3ff42b``
   115  
   116     * Store the compressed VM image under a directory (``/tmp/_images``).
   117  
   118     .. code-block:: shell-session
   119  
   120        $ mkdir -p /tmp/_images
   121        $ kernel_tag="bpf-next-20230526.105339@sha256:4133d4e09b1e86ac175df8d899873180281bb4220dc43e2566c47b0241637411"
   122        $ docker run -v /tmp/_images:/mnt/images \
   123           "quay.io/lvh-images/kind:${kernel_tag}" \
   124           cp -r /data/images/. /mnt/images/
   125  
   126     * Uncompress the VM image into a directory.
   127  
   128     .. code-block:: shell-session
   129  
   130        $ zstd -d /tmp/_images/kind_*.qcow2.zst -o /tmp/_images/datapath-conformance.qcow2
   131  
   132     * Provision the VM. **Qemu will use the current terminal to provision the VM
   133       and will mount the current directory into the VM under** ``/host``.
   134  
   135     .. code-block:: shell-session
   136  
   137        $ qemu-system-x86_64 \
   138            -nodefaults \
   139            -no-reboot \
   140            -smp 4 \
   141            -m 12G \
   142            -enable-kvm \
   143            -cpu host \
   144            -hda /tmp/_images/datapath-conformance.qcow2 \
   145            -netdev user,id=user.0,hostfwd=tcp::2222-:22 \
   146            -device virtio-net-pci,netdev=user.0 \
   147            -fsdev local,id=host_id,path=./,security_model=none \
   148            -device virtio-9p-pci,fsdev=host_id,mount_tag=host_mount \
   149            -serial mon:stdio
   150  
   151  #. Installing dependencies in the VM (``helm``).
   152  
   153     .. code-block:: shell-session
   154  
   155        $ ssh -p 2222 -o "StrictHostKeyChecking=no" root@localhost
   156        # echo "nameserver 8.8.8.8" > /etc/resolv.conf
   157        # git config --global --add safe.directory /host
   158        # cp /host/helm /usr/bin
   159  
   160     .. _install_kind:
   161  
   162  #. The VM is ready to be used for tests. Similarly to the GitHub Action, Kind
   163     will also be used to run the CI. The provisioning of Kind is different
   164     depending on the kernel version that is used, i.e., ginkgo tests are meant
   165     to run on differently when running on bpf-next.
   166  
   167     .. code-block:: shell-session
   168  
   169        $ ssh -p 2222 -o "StrictHostKeyChecking=no" root@localhost
   170        # cd /host/
   171        # kernel_tag="bpf-next-20230526.105339@sha256:4133d4e09b1e86ac175df8d899873180281bb4220dc43e2566c47b0241637411"
   172        # kubernetes_image="kindest/node:v1.27.1@sha256:b7d12ed662b873bd8510879c1846e87c7e676a79fefc93e17b2a52989d3ff42b"
   173        # ip_family="dual" # replace with "ipv4" if k8s 1.19
   174        #
   175        # if [[ "${kernel_tag}" == bpf-next-* ]]; then
   176        #  ./contrib/scripts/kind.sh "" 2 "" "${kubernetes_image}" "none" "${ip_family}"
   177        #  kubectl label node kind-worker2 cilium.io/ci-node=kind-worker2
   178        #  # Avoid re-labeling this node by setting "node-role.kubernetes.io/controlplane"
   179        #  kubectl label node kind-worker2 node-role.kubernetes.io/controlplane=
   180        # else
   181        #   ./contrib/scripts/kind.sh "" 1 "" "${kubernetes_image}" "iptables" "${ip_family}"
   182        # fi
   183        ## Some tests using demo-customcalls.yaml are mounting this directoy
   184        # mkdir -p /home/vagrant/go/src/github.com/cilium
   185        # ln -s /host /home/vagrant/go/src/github.com/cilium/cilium
   186        # git config --global --add safe.directory /cilium
   187  
   188     Verify that kind is running inside the VM:
   189  
   190     .. code-block:: shell-session
   191  
   192        $ ssh -p 2222 -o "StrictHostKeyChecking=no" root@localhost
   193        # kubectl get pods -A
   194        NAMESPACE            NAME                                         READY   STATUS    RESTARTS   AGE
   195        kube-system          coredns-787d4945fb-hqzpb                     0/1     Pending   0          42s
   196        kube-system          coredns-787d4945fb-tkq86                     0/1     Pending   0          42s
   197        kube-system          etcd-kind-control-plane                      1/1     Running   0          57s
   198        kube-system          kube-apiserver-kind-control-plane            1/1     Running   0          57s
   199        kube-system          kube-controller-manager-kind-control-plane   1/1     Running   0          56s
   200        kube-system          kube-scheduler-kind-control-plane            1/1     Running   0          56s
   201        local-path-storage   local-path-provisioner-6bd6454576-648bk      0/1     Pending   0          42s
   202  
   203  #. Now that Kind is provisioned, the tests can be executed inside the VM.
   204     Let us first retrieve the focus regex, under ``cliFocus``, of
   205     ``f09-datapath-misc-2`` from ``.github/actions/ginkgo/main-focus.yaml``.
   206  
   207     * ``cliFocus="K8sDatapathConfig Check|K8sDatapathConfig IPv4Only|K8sDatapathConfig High-scale|K8sDatapathConfig Iptables|K8sDatapathConfig IPv4Only|K8sDatapathConfig IPv6|K8sDatapathConfig Transparent"``
   208  
   209     Run the binary ``test.test`` that was compiled in the previous step. The
   210     following code block is exactly the same as used on the GitHub workflow with
   211     one exception: the flag ``-cilium.holdEnvironment=true``. This flag
   212     will hold the testing environment in case the test fails to allow for further
   213     diagnosis of the current cluster.
   214  
   215     .. code-block:: shell-session
   216  
   217        $ ssh -p 2222 -o "StrictHostKeyChecking=no" root@localhost
   218        # cd /host/test
   219        # kernel_tag="bpf-next-20230526.105339@sha256:4133d4e09b1e86ac175df8d899873180281bb4220dc43e2566c47b0241637411"
   220        # k8s_version="1.27"
   221        #
   222        # export K8S_NODES=2
   223        # export NETNEXT=0
   224        # export K8S_VERSION="${k8s_version}"
   225        # export CNI_INTEGRATION=kind
   226        # export INTEGRATION_TESTS=true
   227        #
   228        # if [[ "${kernel_tag}" == bpf-next-* ]]; then
   229        #    export KERNEL=net-next
   230        #    export NETNEXT=1
   231        #    export KUBEPROXY=0
   232        #    export K8S_NODES=3
   233        #    export NO_CILIUM_ON_NODES=kind-worker2
   234        # elif [[ "${kernel_tag}" == 5.4-* ]]; then
   235        #    export KERNEL=54
   236        # fi
   237        #
   238        # # GitHub actions do not support IPv6 connectivity to outside
   239        # # world. If the infrastructure environment supports it, then
   240        # # this line can be removed
   241        # export CILIUM_NO_IPV6_OUTSIDE=true
   242        #
   243        # commit_sha="7b368923823e63c9824ea2b5ee4dc026bc4d5cd8"
   244        # cliFocus="K8sDatapathConfig Check|K8sDatapathConfig IPv4Only|K8sDatapathConfig High-scale|K8sDatapathConfig Iptables|K8sDatapathConfig IPv4Only|K8sDatapathConfig IPv6|K8sDatapathConfig Transparent"
   245        # quay_org="cilium"
   246        #
   247        # ./test.test \
   248          --ginkgo.focus="${cliFocus}" \
   249          --ginkgo.skip="" \
   250          --ginkgo.seed=1679952881 \
   251          --ginkgo.v -- \
   252          -cilium.provision=false \
   253          -cilium.image=quay.io/${quay_org}/cilium-ci \
   254          -cilium.tag=${commit_sha}  \
   255          -cilium.operator-image=quay.io/${quay_org}/operator \
   256          -cilium.operator-tag=${commit_sha} \
   257          -cilium.hubble-relay-image=quay.io/${quay_org}/hubble-relay-ci \
   258          -cilium.hubble-relay-tag=${commit_sha} \
   259          -cilium.kubeconfig=/root/.kube/config \
   260          -cilium.provision-k8s=false \
   261          -cilium.operator-suffix=-ci \
   262          -cilium.holdEnvironment=true
   263        Using CNI_INTEGRATION="kind"
   264        Running Suite: Suite-k8s-1.27
   265        =============================
   266        Random Seed: 1679952881
   267        Will run 7 of 132 specs
   268  
   269  #. Wait until the test execution completes.
   270  
   271     .. code-block:: shell-session
   272  
   273        Ran 7 of 132 Specs in 721.007 seconds
   274        SUCCESS! -- 7 Passed | 0 Failed | 0 Pending | 125 Skipped
   275  
   276  #. Clean up.
   277  
   278     Once tests are performed, terminate qemu to halt the VM:
   279  
   280     .. code-block:: shell-session
   281  
   282        $ pkill qemu-system-x86
   283  
   284     The VM state is kept in ``/tmp/_images/datapath-conformance.qcow2`` and the
   285     dependencies are installed. Thus steps up to and excluding step
   286     :ref:`installing kind <install_kind>` can be skipped next time and the VM
   287     state can be re-used from step :ref:`installing kind <install_kind>` onwards.
   288  
   289  Running All Ginkgo Tests
   290  ^^^^^^^^^^^^^^^^^^^^^^^^
   291  
   292  Running all of the Ginkgo tests may take an hour or longer. To run all the
   293  ginkgo tests, invoke the make command as follows from the root of the cilium
   294  repository:
   295  
   296  .. code-block:: shell-session
   297  
   298      $ sudo make -C test/ test
   299  
   300  The first time that this is invoked, the testsuite will pull the
   301  `testing VMs <https://app.vagrantup.com/cilium/boxes/ginkgo>`_ and provision
   302  Cilium into them. This may take several minutes, depending on your internet
   303  connection speed. Subsequent runs of the test will reuse the image.
   304  
   305  Running Runtime Tests
   306  ^^^^^^^^^^^^^^^^^^^^^
   307  
   308  To run all of the runtime tests, execute the following command from the ``test`` directory:
   309  
   310  .. code-block:: shell-session
   311  
   312      INTEGRATION_TESTS=true ginkgo --focus="Runtime"
   313  
   314  Ginkgo searches for all tests in all subdirectories that are "named" beginning
   315  with the string "Runtime" and contain any characters after it. For instance,
   316  here is an example showing what tests will be ran using Ginkgo's dryRun option:
   317  
   318  .. code-block:: shell-session
   319  
   320      $ INTEGRATION_TESTS=true ginkgo --focus="Runtime" -dryRun
   321      Running Suite: runtime
   322      ======================
   323      Random Seed: 1516125117
   324      Will run 42 of 164 specs
   325      ................
   326      RuntimePolicyEnforcement Policy Enforcement Always
   327        Always to Never with policy
   328        /Users/ianvernon/go/src/github.com/cilium/cilium/test/runtime/Policies.go:258
   329      •
   330      ------------------------------
   331      RuntimePolicyEnforcement Policy Enforcement Always
   332        Always to Never without policy
   333        /Users/ianvernon/go/src/github.com/cilium/cilium/test/runtime/Policies.go:293
   334      •
   335      ------------------------------
   336      RuntimePolicyEnforcement Policy Enforcement Never
   337        Container creation
   338        /Users/ianvernon/go/src/github.com/cilium/cilium/test/runtime/Policies.go:332
   339      •
   340      ------------------------------
   341      RuntimePolicyEnforcement Policy Enforcement Never
   342        Never to default with policy
   343        /Users/ianvernon/go/src/github.com/cilium/cilium/test/runtime/Policies.go:349
   344      .................
   345      Ran 42 of 164 Specs in 0.002 seconds
   346      SUCCESS! -- 0 Passed | 0 Failed | 0 Pending | 122 Skipped PASS
   347  
   348      Ginkgo ran 1 suite in 1.830262168s
   349      Test Suite Passed
   350  
   351  The output has been truncated. For more information about this functionality,
   352  consult the aforementioned Ginkgo documentation.
   353  
   354  .. _running_k8s_tests:
   355  
   356  Running Kubernetes Tests
   357  ^^^^^^^^^^^^^^^^^^^^^^^^
   358  
   359  To run all of the Kubernetes tests, run the following command from the ``test`` directory:
   360  
   361  .. code-block:: shell-session
   362  
   363      INTEGRATION_TESTS=true ginkgo --focus="K8s"
   364  
   365  To run a specific test from the Kubernetes tests suite, run the following command
   366  from the ``test`` directory:
   367  
   368  .. code-block:: shell-session
   369  
   370      INTEGRATION_TESTS=true ginkgo --focus="K8s.*Check iptables masquerading with random-fully"
   371  
   372  Similar to the Runtime test suite, Ginkgo searches for all tests in all
   373  subdirectories that are "named" beginning with the string "K8s" and
   374  contain any characters after it.
   375  
   376  The Kubernetes tests support the following Kubernetes versions:
   377  
   378  * 1.19
   379  * 1.20
   380  * 1.21
   381  * 1.22
   382  * 1.23
   383  * 1.24
   384  * 1.25
   385  * 1.26
   386  * 1.27
   387  * 1.28
   388  
   389  By default, the Vagrant VMs are provisioned with Kubernetes 1.23. To run with any other
   390  supported version of Kubernetes, run the test suite with the following format:
   391  
   392  .. code-block:: shell-session
   393  
   394      INTEGRATION_TESTS=true K8S_VERSION=<version> ginkgo --focus="K8s"
   395  
   396  .. note::
   397  
   398     When provisioning VMs with the net-next kernel (``NETNEXT=1``) on
   399     VirtualBox which version does not match a version of the VM image
   400     VirtualBox Guest Additions, Vagrant will install a new version of
   401     the Additions with ``mount.vboxsf``. The latter is not compatible with
   402     ``vboxsf.ko`` shipped within the VM image, and thus syncing of shared
   403     folders will not work.
   404  
   405     To avoid this, one can prevent Vagrant from installing the Additions by
   406     putting the following into ``$HOME/.vagrant.d/Vagrantfile``:
   407  
   408     .. code-block:: ruby
   409  
   410        Vagrant.configure('2') do |config|
   411          if Vagrant.has_plugin?("vagrant-vbguest") then
   412            config.vbguest.auto_update = false
   413          end
   414  
   415          config.vm.provider :virtualbox do |vbox|
   416            vbox.check_guest_additions = false
   417          end
   418        end
   419  
   420  Available CLI Options
   421  ^^^^^^^^^^^^^^^^^^^^^
   422  
   423  For more advanced workflows, check the list of available custom options for the Cilium
   424  framework in the ``test/`` directory and interact with ginkgo directly:
   425  
   426  .. code-block:: shell-session
   427  
   428      $ cd test/
   429      $ ginkgo . -- -cilium.help
   430        -cilium.SSHConfig string
   431              Specify a custom command to fetch SSH configuration (eg: 'vagrant ssh-config')
   432        -cilium.help
   433              Display this help message.
   434        -cilium.holdEnvironment
   435              On failure, hold the environment in its current state
   436        -cilium.hubble-relay-image string
   437              Specifies which image of hubble-relay to use during tests
   438        -cilium.hubble-relay-tag string
   439              Specifies which tag of hubble-relay to use during tests
   440        -cilium.image string
   441              Specifies which image of cilium to use during tests
   442        -cilium.kubeconfig string
   443              Kubeconfig to be used for k8s tests
   444        -cilium.multinode
   445              Enable tests across multiple nodes. If disabled, such tests may silently pass (default true)
   446        -cilium.operator-image string
   447              Specifies which image of cilium-operator to use during tests
   448        -cilium.operator-tag string
   449              Specifies which tag of cilium-operator to use during tests
   450        -cilium.passCLIEnvironment
   451              Pass the environment invoking ginkgo, including PATH, to subcommands
   452        -cilium.provision
   453              Provision Vagrant boxes and Cilium before running test (default true)
   454        -cilium.provision-k8s
   455              Specifies whether Kubernetes should be deployed and installed via kubeadm or not (default true)
   456        -cilium.runQuarantined
   457              Run tests that are under quarantine.
   458        -cilium.showCommands
   459              Output which commands are ran to stdout
   460        -cilium.skipLogs
   461              skip gathering logs if a test fails
   462        -cilium.tag string
   463              Specifies which tag of cilium to use during tests
   464        -cilium.testScope string
   465              Specifies scope of test to be ran (k8s, runtime)
   466        -cilium.timeout duration
   467              Specifies timeout for test run (default 24h0m0s)
   468  
   469      Ginkgo ran 1 suite in 4.312100241s
   470      Test Suite Failed
   471  
   472  For more information about other built-in options to Ginkgo, consult the
   473  `ginkgo-documentation`_.
   474  
   475  .. _ginkgo-documentation:
   476  
   477  Running Specific Tests Within a Test Suite
   478  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   479  
   480  If you want to run one specified test, there are a few options:
   481  
   482  * By modifying code: add the prefix "FIt" on the test you want to run; this
   483    marks the test as focused. Ginkgo will skip other tests and will only run the
   484    "focused" test. For more information, consult the `Focused Specs`_
   485    documentation from Ginkgo.
   486  
   487    .. code-block:: go
   488  
   489        It("Example test", func(){
   490            Expect(true).Should(BeTrue())
   491        })
   492  
   493        FIt("Example focused test", func(){
   494            Expect(true).Should(BeTrue())
   495        })
   496  
   497  
   498  * From the command line: specify a more granular focus if you want to focus on, say, Runtime L7 tests:
   499  
   500    .. code-block:: shell-session
   501  
   502        INTEGRATION_TESTS=true ginkgo --focus "Runtime.*L7"
   503  
   504  
   505  This will focus on tests that contain "Runtime", followed by any
   506  number of any characters, followed by "L7". ``--focus`` is a regular
   507  expression and quotes are required if it contains spaces and to escape
   508  shell expansion of ``*``.
   509  
   510  .. _Focused Specs: https://onsi.github.io/ginkgo/#focused-specs
   511  
   512  Compiling the tests without running them
   513  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   514  
   515  To validate that the Go code you've written for testing is correct without
   516  needing to run the full test, you can build the test directory:
   517  
   518  .. code-block:: shell-session
   519  
   520      make -C test/ build
   521  
   522  Updating Cilium images for Kubernetes tests
   523  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   524  
   525  Sometimes when running the CI suite for a feature under development, it's common
   526  to re-run the CI suite on the CI VMs running on a local development machine after
   527  applying some changes to Cilium. For this the new Cilium images have to be
   528  built, and then used by the CI suite. To do so, one can run the following
   529  commands on the ``k8s1`` VM:
   530  
   531  .. code-block:: shell-session
   532  
   533     cd go/src/github.com/cilium/cilium
   534  
   535     make LOCKDEBUG=1 docker-cilium-image
   536     docker tag quay.io/cilium/cilium:latest \
   537  	k8s1:5000/cilium/cilium-dev:latest
   538     docker push k8s1:5000/cilium/cilium-dev:latest
   539  
   540     make -B LOCKDEBUG=1 docker-operator-generic-image
   541     docker tag quay.io/cilium/operator-generic:latest \
   542  	k8s1:5000/cilium/operator-generic:latest
   543     docker push k8s1:5000/cilium/operator-generic:latest
   544  
   545  The commands were adapted from the ``test/provision/compile.sh`` script.
   546  
   547  Test Reports
   548  ~~~~~~~~~~~~
   549  
   550  The Cilium Ginkgo framework formulates JUnit reports for each test. The
   551  following files currently are generated depending upon the test suite that is ran:
   552  
   553  * runtime.xml
   554  * K8s.xml
   555  
   556  Best Practices for Writing Tests
   557  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   558  
   559  * Provide informative output to console during a test using the `By construct <https://onsi.github.io/ginkgo/#documenting-complex-specs-by>`_. This helps with debugging and gives those who did not write the test a good idea of what is going on. The lower the barrier of entry is for understanding tests, the better our tests will be!
   560  * Leave the testing environment in the same state that it was in when the test started by deleting resources, resetting configuration, etc.
   561  * Gather logs in the case that a test fails. If a test fails while running on Jenkins, a postmortem needs to be done to analyze why. So, dumping logs to a location where Jenkins can pick them up is of the highest imperative. Use the following code in an ``AfterFailed`` method:
   562  
   563  .. code-block:: go
   564  
   565  	AfterFailed(func() {
   566  		vm.ReportFailed()
   567  	})
   568  
   569  
   570  Ginkgo Extensions
   571  ~~~~~~~~~~~~~~~~~
   572  
   573  In Cilium, some Ginkgo features are extended to cover some uses cases that are
   574  useful for testing Cilium.
   575  
   576  BeforeAll
   577  ^^^^^^^^^
   578  
   579  This function will run before all `BeforeEach`_ within a `Describe or Context`_.
   580  This method is an equivalent to ``SetUp`` or initialize functions in common
   581  unit test frameworks.
   582  
   583  .. _BeforeEach: https://onsi.github.io/ginkgo/#extracting-common-setup-beforeeach
   584  .. _Describe or Context: https://onsi.github.io/ginkgo/#organizing-specs-with-container-nodes
   585  
   586  AfterAll
   587  ^^^^^^^^
   588  
   589  This method will run after all `AfterEach`_ functions defined in a `Describe or Context`_.
   590  This method is used for tearing down objects created which are used by all
   591  ``Its`` within the given ``Context`` or ``Describe``. It is ran after all Its
   592  have ran, this method is a equivalent to ``tearDown`` or ``finalize`` methods in
   593  common unit test frameworks.
   594  
   595  A good use case for using ``AfterAll`` method is to remove containers or pods
   596  that are needed for multiple ``Its`` in the given ``Context`` or ``Describe``.
   597  
   598  .. _AfterEach: BeforeEach_
   599  
   600  JustAfterEach
   601  ^^^^^^^^^^^^^
   602  
   603  This method will run just after each test and before ``AfterFailed`` and
   604  ``AfterEach``. The main reason of this method is to perform some assertions
   605  for a group of tests.  A good example of using a global ``JustAfterEach``
   606  function is for deadlock detection, which checks the Cilium logs for deadlocks
   607  that may have occurred in the duration of the tests.
   608  
   609  AfterFailed
   610  ^^^^^^^^^^^
   611  
   612  This method will run before all ``AfterEach`` and after ``JustAfterEach``. This
   613  function is only called when the test failed.This construct is used to gather
   614  logs, the status of Cilium, etc, which provide data for analysis when tests
   615  fail.
   616  
   617  Example Test Layout
   618  ^^^^^^^^^^^^^^^^^^^
   619  
   620  Here is an example layout of how a test may be written with the aforementioned
   621  constructs:
   622  
   623  Test description diagram::
   624  
   625      Describe
   626          BeforeAll(A)
   627          AfterAll(A)
   628          AfterFailed(A)
   629          AfterEach(A)
   630          JustAfterEach(A)
   631          TESTA1
   632          TESTA2
   633          TESTA3
   634          Context
   635              BeforeAll(B)
   636              AfterAll(B)
   637              AfterFailed(B)
   638              AfterEach(B)
   639              JustAfterEach(B)
   640              TESTB1
   641              TESTB2
   642              TESTB3
   643  
   644  
   645  Test execution flow::
   646  
   647      Describe
   648          BeforeAll
   649          TESTA1; JustAfterEach(A), AfterFailed(A), AfterEach(A)
   650          TESTA2; JustAfterEach(A), AfterFailed(A), AfterEach(A)
   651          TESTA3; JustAfterEach(A), AfterFailed(A), AfterEach(A)
   652          Context
   653              BeforeAll(B)
   654              TESTB1:
   655                 JustAfterEach(B); JustAfterEach(A)
   656                 AfterFailed(B); AfterFailed(A);
   657                 AfterEach(B) ; AfterEach(A);
   658              TESTB2:
   659                 JustAfterEach(B); JustAfterEach(A)
   660                 AfterFailed(B); AfterFailed(A);
   661                 AfterEach(B) ; AfterEach(A);
   662              TESTB3:
   663                 JustAfterEach(B); JustAfterEach(A)
   664                 AfterFailed(B); AfterFailed(A);
   665                 AfterEach(B) ; AfterEach(A);
   666              AfterAll(B)
   667          AfterAll(A)
   668  
   669  Debugging:
   670  ~~~~~~~~~~
   671  
   672  You can retrieve all run commands and their output in the report directory
   673  (``./test/test_results``). Each test creates a new folder, which contains
   674  a file called log where all information is saved, in case of a failing
   675  test an exhaustive data will be added.
   676  
   677  .. code-block:: shell-session
   678  
   679  	$ head test/test_results/RuntimeKafkaKafkaPolicyIngress/logs
   680  	level=info msg=Starting testName=RuntimeKafka
   681  	level=info msg="Vagrant: running command \"vagrant ssh-config runtime\""
   682  	cmd: "sudo cilium-dbg status" exitCode: 0
   683  	 KVStore:            Ok         Consul: 172.17.0.3:8300
   684  	ContainerRuntime:   Ok
   685  	Kubernetes:         Disabled
   686  	Kubernetes APIs:    [""]
   687  	Cilium:             Ok   OK
   688  	NodeMonitor:        Disabled
   689  	Allocated IPv4 addresses:
   690  
   691  
   692  Running with delve
   693  ^^^^^^^^^^^^^^^^^^
   694  
   695  `Delve <https://github.com/derekparker/delve>`_ is a debugging tool for Go
   696  applications. If you want to run your test with delve,  you should add a new
   697  breakpoint using
   698  `runtime.BreakPoint() <https://golang.org/pkg/runtime/#Breakpoint>`_ in the
   699  code, and run ginkgo using ``dlv``.
   700  
   701  Example how to run ginkgo using ``dlv``:
   702  
   703  .. code-block:: shell-session
   704  
   705  	dlv test . -- --ginkgo.focus="Runtime" -ginkgo.v=true --cilium.provision=false
   706  
   707  Running End-To-End Tests In Other Environments via kubeconfig
   708  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   709  
   710  The end-to-end tests can be run with an arbitrary kubeconfig file. Normally the
   711  CI will use the kubernetes created via vagrant but this can be overridden with
   712  ``--cilium.kubeconfig``. When used, ginkgo will not start a VM nor compile
   713  cilium. It will also skip some setup tasks like labeling nodes for testing.
   714  
   715  This mode expects:
   716  
   717  - The current directory is ``cilium/test``
   718  
   719  - A test focus with ``--focus``. ``--focus="K8s"`` selects all kubernetes tests.
   720    If not passing ``--focus=K8s`` then you must pass ``-cilium.testScope=K8s``.
   721  
   722  - Cilium images as full URLs specified with the ``--cilium.image`` and
   723    ``--cilium.operator-image`` options.
   724  
   725  - A working kubeconfig with the ``--cilium.kubeconfig`` option
   726  
   727  - A populated K8S_VERSION environment variable set to the version of the cluster
   728  
   729  - If appropriate, set the ``CNI_INTEGRATION`` environment variable set to one
   730    of ``gke``, ``eks``, ``eks-chaining``, ``microk8s`` or ``minikube``. This selects
   731    matching configuration overrides for cilium.
   732    Leaving this unset for non-matching integrations is also correct.
   733  
   734    For k8s environments that invoke an authentication agent, such as EKS and
   735    ``aws-iam-authenticator``, set ``--cilium.passCLIEnvironment=true``
   736  
   737  An example invocation is
   738  
   739  .. code-block:: shell-session
   740  
   741    INTEGRATION_TESTS=true CNI_INTEGRATION=eks K8S_VERSION=1.16 ginkgo --focus="K8s" -- -cilium.provision=false -cilium.kubeconfig=`echo ~/.kube/config` -cilium.image="quay.io/cilium/cilium-ci" -cilium.operator-image="quay.io/cilium/operator" -cilium.operator-suffix="-ci" -cilium.passCLIEnvironment=true
   742  
   743  
   744  To run tests with Kind, try
   745  
   746  .. code-block:: shell-session
   747  
   748    K8S_VERSION=1.25 ginkgo --focus=K8s -- -cilium.provision=false --cilium.image=localhost:5000/cilium/cilium-dev -cilium.tag=local  --cilium.operator-image=localhost:5000/cilium/operator -cilium.operator-tag=local -cilium.kubeconfig=`echo ~/.kube/config` -cilium.provision-k8s=false  -cilium.testScope=K8s -cilium.operator-suffix=
   749  
   750  
   751  Running in GKE
   752  ^^^^^^^^^^^^^^
   753  
   754  1- Setup a cluster as in :ref:`k8s_install_quick` or utilize an existing
   755  cluster.
   756  
   757  .. note:: You do not need to deploy Cilium in this step, as the End-To-End
   758            Testing Framework handles the deployment of Cilium.
   759  
   760  .. note:: The tests require machines larger than ``n1-standard-4``. This can be
   761            set with ``--machine-type n1-standard-4`` on cluster creation.
   762  
   763  
   764  2- Invoke the tests from ``cilium/test`` with options set as explained in
   765  `Running End-To-End Tests In Other Environments via kubeconfig`_
   766  
   767  .. note:: The tests require the ``NATIVE_CIDR`` environment variable to be set to
   768            the value of the cluster IPv4 CIDR returned by the ``gcloud container
   769            clusters describe`` command.
   770  
   771  .. code-block:: shell-session
   772  
   773    export CLUSTER_NAME=cluster1
   774    export CLUSTER_ZONE=us-west2-a
   775    export NATIVE_CIDR="$(gcloud container clusters describe $CLUSTER_NAME --zone $CLUSTER_ZONE --format 'value(clusterIpv4Cidr)')"
   776  
   777    INTEGRATION_TESTS=true CNI_INTEGRATION=gke K8S_VERSION=1.17 ginkgo --focus="K8sDemo" -- -cilium.provision=false -cilium.kubeconfig=`echo ~/.kube/config` -cilium.image="quay.io/cilium/cilium-ci" -cilium.operator-image="quay.io/cilium/operator" -cilium.operator-suffix="-ci" -cilium.hubble-relay-image="quay.io/cilium/hubble-relay-ci" -cilium.passCLIEnvironment=true
   778  
   779  .. note:: The kubernetes version defaults to 1.23 but can be configured with
   780            versions between 1.16 and 1.23. Version should match the server
   781            version reported by ``kubectl version``.
   782  
   783  AKS (experimental)
   784  ^^^^^^^^^^^^^^^^^^
   785  
   786  .. note:: The tests require the ``NATIVE_CIDR`` environment variable to be set to
   787            the value of the cluster IPv4 CIDR.
   788  
   789  1. Setup a cluster as in :ref:`k8s_install_quick` or utilize an existing
   790     cluster. You do not need to deploy Cilium in this step, as the End-To-End
   791     Testing Framework handles the deployment of Cilium.
   792  
   793  2. Invoke the tests from ``cilium/test`` with options set as explained in
   794  `Running End-To-End Tests In Other Environments via kubeconfig`_
   795  
   796  .. code-block:: shell-session
   797  
   798      export NATIVE_CIDR="10.241.0.0/16"
   799      INTEGRATION_TESTS=true CNI_INTEGRATION=aks K8S_VERSION=1.17 ginkgo --focus="K8s" -- -cilium.provision=false -cilium.kubeconfig=`echo ~/.kube/config` -cilium.passCLIEnvironment=true -cilium.image="mcr.microsoft.com/oss/cilium/cilium" -cilium.tag="1.12.1" -cilium.operator-image="mcr.microsoft.com/oss/cilium/operator" -cilium.operator-suffix=""  -cilium.operator-tag="1.12.1"
   800  
   801  AWS EKS (experimental)
   802  ^^^^^^^^^^^^^^^^^^^^^^
   803  
   804  Not all tests can succeed on EKS. Many do, however and may be useful.
   805  :gh-issue:`9678#issuecomment-749350425` contains a list of tests that are still
   806  failing.
   807  
   808  1. Setup a cluster as in :ref:`k8s_install_quick` or utilize an existing
   809     cluster.
   810  
   811  2. Source the testing integration script from ``cilium/contrib/testing/integrations.sh``.
   812  
   813  3. Invoke the ``gks`` function by passing which ``cilium`` docker image to run
   814     and the test focus. The command also accepts additional ginkgo arguments.
   815  
   816  .. code-block:: shell-session
   817  
   818      gks quay.io/cilium/cilium:latest K8sDemo
   819  
   820  
   821  Adding new Managed Kubernetes providers
   822  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   823  
   824  All Managed Kubernetes test support relies on using a pre-configured kubeconfig
   825  file.  This isn't always adequate, however, and adding defaults specific to
   826  each provider is possible. The `commit adding GKE <https://github.com/cilium/cilium/commit/c2d8445fd725c515a635c8c3ad3be901a08084eb>`_
   827  support is a good reference.
   828  
   829  1. Add a map of helm settings to act as an override for this provider in
   830     `test/helpers/kubectl.go <https://github.com/cilium/cilium/blob/26dec4c4f4311df2b1a6c909b27ff7fe6e46929f/test/helpers/kubectl.go#L80-L102>`_.
   831     These should be the helm settings used when generating cilium specs for this
   832     provider.
   833  
   834  2. Add a unique `CI Integration constant <https://github.com/cilium/cilium/blob/26dec4c4f4311df2b1a6c909b27ff7fe6e46929f/test/helpers/kubectl.go#L66-L67>`_.
   835     This value is passed in when invoking ginkgo via the ``CNI_INTEGRATON``
   836     environment variable.
   837  
   838  3. Update the `helm overrides <https://github.com/cilium/cilium/blob/26dec4c4f4311df2b1a6c909b27ff7fe6e46929f/test/helpers/kubectl.go#L138-L147>`_
   839     mapping with the constant and the helm settings.
   840  
   841  4. For cases where a test should be skipped use the ``SkipIfIntegration``. To
   842     skip whole contexts, use ``SkipContextIf``. More complex logic can be
   843     expressed with functions like ``IsIntegration``. These functions are all
   844     part of the `test/helpers <https://github.com/cilium/cilium/tree/26dec4c4f4311df2b1a6c909b27ff7fe6e46929f/test/helpers>`_
   845     package.
   846  
   847  Running End-To-End Tests In Other Environments via SSH
   848  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   849  
   850  If you want to run tests in an arbitrary environment with SSH access, you can
   851  use ``--cilium.SSHConfig`` to provide the SSH configuration of the endpoint on
   852  which tests will be run. The tests presume the following on the remote
   853  instance:
   854  
   855  - Cilium source code is located in the directory ``/home/vagrant/go/src/github.com/cilium/cilium/``.
   856  - Cilium is installed and running.
   857  
   858  The ssh connection needs to be defined as a ``ssh-config`` file and need to have
   859  the following targets:
   860  
   861  - runtime: To run runtime tests
   862  - k8s{1..2}-${K8S_VERSION}: to run Kubernetes tests. These instances must have
   863    Kubernetes installed and running as a prerequisite for running tests.
   864  
   865  An example ``ssh-config`` can be the following:
   866  
   867  ::
   868  
   869  	Host runtime
   870  	  HostName 127.0.0.1
   871  	  User vagrant
   872  	  Port 2222
   873  	  UserKnownHostsFile /dev/null
   874  	  StrictHostKeyChecking no
   875  	  PasswordAuthentication no
   876  	  IdentityFile /home/eloy/.go/src/github.com/cilium/cilium/test/.vagrant/machines/runtime/virtualbox/private_key
   877  	  IdentitiesOnly yes
   878  	  LogLevel FATAL
   879  
   880  To run this you can use the following command:
   881  
   882  .. code-block:: shell-session
   883  
   884      ginkgo -- --cilium.provision=false --cilium.SSHConfig="cat ssh-config"
   885  
   886  
   887  VMs for Testing
   888  ~~~~~~~~~~~~~~~
   889  
   890  The VMs used for testing are defined in ``test/Vagrantfile``. There are a variety of
   891  configuration options that can be passed as environment variables:
   892  
   893  +----------------------+-------------------+--------------+------------------------------------------------------------------+
   894  | ENV variable         | Default Value     | Options      | Description                                                      |
   895  +======================+===================+==============+==================================================================+
   896  | K8S\_NODES           | 2                 | 0..100       | Number of Kubernetes nodes in the cluster                        |
   897  +----------------------+-------------------+--------------+------------------------------------------------------------------+
   898  | NO_CILIUM_ON_NODE[S] | none              | \*           | Comma-separated list of K8s nodes that should not run Cilium     |
   899  +----------------------+-------------------+--------------+------------------------------------------------------------------+
   900  | NFS                  | 0                 | 1            | If Cilium folder needs to be shared using NFS                    |
   901  +----------------------+-------------------+--------------+------------------------------------------------------------------+
   902  | IPv6                 | 0                 | 0-1          | If 1 the Kubernetes cluster will use IPv6                        |
   903  +----------------------+-------------------+--------------+------------------------------------------------------------------+
   904  | CONTAINER\_RUNTIME   | docker            | containerd   | To set the default container runtime in the Kubernetes cluster   |
   905  +----------------------+-------------------+--------------+------------------------------------------------------------------+
   906  | K8S\_VERSION         | 1.18              | 1.\*\*       | Kubernetes version to install                                    |
   907  +----------------------+-------------------+--------------+------------------------------------------------------------------+
   908  | KUBEPROXY            | 1                 | 0-1          | If 0 the Kubernetes' kube-proxy won't be installed               |
   909  +----------------------+-------------------+--------------+------------------------------------------------------------------+
   910  | SERVER\_BOX          | cilium/ubuntu-dev | \*           | Vagrantcloud base image                                          |
   911  +----------------------+-------------------+--------------+------------------------------------------------------------------+
   912  | VM\_CPUS             | 2                 | 0..100       | Number of CPUs that need to have the VM                          |
   913  +----------------------+-------------------+--------------+------------------------------------------------------------------+
   914  | VM\_MEMORY           | 4096              | \d+          | RAM size in Megabytes                                            |
   915  +----------------------+-------------------+--------------+------------------------------------------------------------------+
   916  
   917  VM images
   918  ~~~~~~~~~
   919  
   920  The test suite relies on Vagrant to automatically download the required VM
   921  image, if it is not already available on the system. VM images weight several
   922  gigabytes so this may take some time, but faster tools such as `aria2`_ can
   923  speed up the process by opening multiple connections. The script
   924  `contrib/scripts/add_vagrant_box.sh`_ can be useful to manually download
   925  selected images with aria2 prior to launching the test suite, or to
   926  periodically update images in a ``cron`` job::
   927  
   928      $ bash contrib/scripts/add_vagrant_box.sh -h
   929      usage: add_vagrant_box.sh [options] [vagrant_box_defaults.rb path]
   930              path to vagrant_box_defaults.rb defaults to ./vagrant_box_defaults.rb
   931  
   932      options:
   933              -a              use aria2c instead of curl
   934              -b <box>        download selected box (defaults: ubuntu ubuntu-next)
   935              -d <dir>        download to dir instead of /tmp/
   936              -l              download latest versions instead of using vagrant_box_defaults
   937              -h              display this help
   938  
   939      examples:
   940              download boxes ubuntu and ubuntu-next from vagrant_box_defaults.rb:
   941              $ add-vagrant-boxes.sh $HOME/go/src/github.com/cilium/cilium/vagrant_box_defaults.rb
   942              download latest version for ubuntu-dev and ubuntu-next:
   943              $ add-vagrant-boxes.sh -l -b ubuntu-dev -b ubuntu-next
   944              same as above, downloading into /tmp/foo and using aria2c:
   945              $ add-vagrant-boxes.sh -al -d /tmp/foo -b ubuntu-dev -b ubuntu-next
   946  
   947  .. _aria2: https://aria2.github.io/
   948  .. _contrib/scripts/add_vagrant_box.sh:
   949     https://github.com/cilium/cilium/blob/main/contrib/scripts/add_vagrant_box.sh
   950  
   951  Known Issues and Workarounds
   952  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   953  
   954  VirtualBox hostonlyifs and DHCP related errors
   955  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   956  
   957  If you see the following error, take a look at this `GitHub issue
   958  <https://github.com/hashicorp/vagrant/issues/3083#issuecomment-41156076>`_ for
   959  workarounds.
   960  
   961  ::
   962  
   963      A host only network interface you're attempting to configure via DHCP
   964      already has a conflicting host only adapter with DHCP enabled. The
   965      DHCP on this adapter is incompatible with the DHCP settings. Two
   966      host only network interfaces are not allowed to overlap, and each
   967      host only network interface can have only one DHCP server. Please
   968      reconfigure your host only network or remove the virtual machine
   969      using the other host only network.
   970  
   971  Also, consider upgrading VirtualBox and Vagrant to the latest versions.
   972  
   973  Further Assistance
   974  ~~~~~~~~~~~~~~~~~~
   975  
   976  Have a question about how the tests work or want to chat more about improving the
   977  testing infrastructure for Cilium? Hop on over to the ``#testing`` channel on
   978  `Cilium Slack`_.