Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v2.3.2] Don't retry tests at the GHA level #4281

Merged
merged 7 commits into from
Jun 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
52 changes: 22 additions & 30 deletions .github/workflows/execute-tests-and-promote.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,24 +159,20 @@ jobs:
username: ${{ secrets.GH_DOCKER_BUILD_USERNAME }}
password: ${{ secrets.GH_DOCKER_BUILD_TOKEN }}
- name: make pytest-${{ matrix.test }}
uses: nick-invision/retry@v2.4.0
with:
max_attempts: 3
timeout_minutes: 20
command: |
export USE_LOCAL_K3S_CLUSTER=1
sudo sysctl -w fs.file-max=1600000
sudo sysctl -w fs.inotify.max_user_instances=4096
run: |
export USE_LOCAL_K3S_CLUSTER=1
sudo sysctl -w fs.file-max=1600000
sudo sysctl -w fs.inotify.max_user_instances=4096

make ci/setup-k3d K3D_CLUSTER_NAME=amb-ci
make ci/setup-k3d K3D_CLUSTER_NAME=amb-ci

export DEV_KUBE_NO_PVC=yes
export KAT_REQ_LIMIT=900
export TEST_XML_DIR=/tmp/test-logs/xml/
export DEV_KUBECONFIG=~/.kube/config
export DEV_REGISTRY=${{ secrets.DEV_REGISTRY }}
mkdir -p ${TEST_XML_DIR}
make pytest-${{ matrix.test }}
export DEV_KUBE_NO_PVC=yes
export KAT_REQ_LIMIT=900
export TEST_XML_DIR=/tmp/test-logs/xml/
export DEV_KUBECONFIG=~/.kube/config
export DEV_REGISTRY=${{ secrets.DEV_REGISTRY }}
mkdir -p ${TEST_XML_DIR}
make pytest-${{ matrix.test }}
- uses: ./.github/actions/after-job
if: always()
with:
Expand Down Expand Up @@ -206,21 +202,17 @@ jobs:
username: ${{ secrets.GH_DOCKER_BUILD_USERNAME }}
password: ${{ secrets.GH_DOCKER_BUILD_TOKEN }}
- name: make pytest-${{ matrix.test }}
uses: nick-invision/retry@v2.4.0
with:
max_attempts: 3
timeout_minutes: 20
command: |
sudo sysctl -w fs.file-max=1600000
sudo sysctl -w fs.inotify.max_user_instances=4096
run: |
sudo sysctl -w fs.file-max=1600000
sudo sysctl -w fs.inotify.max_user_instances=4096

export DEV_KUBE_NO_PVC=yes
export KAT_REQ_LIMIT=900
export TEST_XML_DIR=/tmp/test-logs/xml/
export DEV_KUBECONFIG=~/.kube/config
export DEV_REGISTRY=${{ secrets.DEV_REGISTRY }}
mkdir -p ${TEST_XML_DIR}
make pytest-${{ matrix.test }}
export DEV_KUBE_NO_PVC=yes
export KAT_REQ_LIMIT=900
export TEST_XML_DIR=/tmp/test-logs/xml/
export DEV_KUBECONFIG=~/.kube/config
export DEV_REGISTRY=${{ secrets.DEV_REGISTRY }}
mkdir -p ${TEST_XML_DIR}
make pytest-${{ matrix.test }}
- uses: ./.github/actions/after-job
if: always()
with:
Expand Down
1 change: 1 addition & 0 deletions pkg/k8s/watcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ func TestWatchCustomCollision(t *testing.T) {
}

func TestWatchQuery(t *testing.T) {
t.Skip("FIXME(lukeshu): This test is notoriously flakey, and the code under test hasn't changed in ages. Write better tests!")
t.Parallel()
ctx := dlog.NewTestContext(t, false)
w, err := k8s.NewWatcher(info(ctx))
Expand Down
27 changes: 26 additions & 1 deletion pkg/snapshot/v1/annotations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,30 @@ service: quote:80
},
}

svcWithEmptyAnnotation := &kates.Service{
TypeMeta: metav1.TypeMeta{
Kind: "Service",
},
ObjectMeta: metav1.ObjectMeta{
Name: "svc-empty",
Namespace: "ambassador",
Annotations: map[string]string{
"getambassador.io/config": "",
},
},
}

svcWithMissingAnnotation := &kates.Service{
TypeMeta: metav1.TypeMeta{
Kind: "Service",
},
ObjectMeta: metav1.ObjectMeta{
Name: "svc-missing",
Namespace: "ambassador",
Annotations: map[string]string{},
},
}

ingHost := `
---
apiVersion: getambassador.io/v3alpha1
Expand Down Expand Up @@ -114,7 +138,7 @@ prefix: /blah/`
}

ks := &snapshotTypes.KubernetesSnapshot{
Services: []*kates.Service{svc, ambSvc},
Services: []*kates.Service{svc, ambSvc, svcWithEmptyAnnotation, svcWithMissingAnnotation},
Ingresses: []*snapshotTypes.Ingress{{Ingress: *ingress}},
Hosts: []*amb.Host{ignoredHost},
}
Expand All @@ -123,6 +147,7 @@ prefix: /blah/`

err := ks.PopulateAnnotations(ctx)
assert.NoError(t, err)
assert.Equal(t, len(ks.Services), 4)
assert.Equal(t, map[string]snapshotTypes.AnnotationList{
"Service/svc.ambassador": {
&amb.Mapping{
Expand Down
4 changes: 2 additions & 2 deletions python/ambassador/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ class Config:
fatal_errors: int
object_errors: int

def __init__(self, logger:logging.Logger=None, schema_dir_path: Optional[str]=None) -> None:
self.logger = logger or logging.getLogger("ambassador.config")
def __init__(self, schema_dir_path: Optional[str]=None) -> None:
self.logger = logging.getLogger("ambassador.config")

if not schema_dir_path:
# Note that this "resource_filename" has to do with setuptool packages, not
Expand Down
2 changes: 1 addition & 1 deletion python/ambassador/fetch/fetcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ def parse_watt(self, serialization: str, finalize: bool=True) -> None:
watt_list.append(obj)

# Remove annotations from the snapshot; we'll process them separately.
annotations = watt_k8s.pop('annotations') or {}
annotations = watt_k8s.pop('annotations', {})

# These objects have to be processed first, in order, as they depend
# on each other.
Expand Down
76 changes: 43 additions & 33 deletions python/tests/unit/test_acme_privatekey_secrets.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,16 @@
from typing import Any, Dict, List, Optional, Union, TextIO, TYPE_CHECKING

import logging
import os
from typing import Optional, Tuple

import hashlib
import io
import json
import logging
import os

import pytest

logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s test %(levelname)s: %(message)s",
datefmt='%Y-%m-%d %H:%M:%S'
)

logger = logging.getLogger("ambassador")
logger.setLevel(logging.DEBUG)

from ambassador import Config, IR
from ambassador.fetch import ResourceFetcher
from ambassador.utils import SecretHandler, SecretInfo, SavedSecret

if TYPE_CHECKING:
from ambassador.ir import IRResource # pragma: no cover
from ambassador.utils import SecretHandler, SavedSecret

# MemorySecretHandler is a degenerate SecretHandler that doesn't actually
# cache anything to disk. It will never load a secret that isn't already
Expand Down Expand Up @@ -73,8 +61,8 @@ def cache_internal(self, name: str, namespace: str,
return SavedSecret(name, namespace, tls_crt_path, tls_key_path, user_key_path, root_crt_path, cert_data)


def _get_ir_config(watt):
aconf = Config(logger=logger)
def _get_config_and_ir(logger: logging.Logger, watt: str) -> Tuple[Config, IR]:
aconf = Config()
fetcher = ResourceFetcher(logger, aconf)
fetcher.parse_watt(watt)
aconf.load_all(fetcher.sorted())
Expand All @@ -85,23 +73,45 @@ def _get_ir_config(watt):
assert ir
return aconf, ir

def _get_errors(caplog: pytest.LogCaptureFixture, logger_name: str, watt_data_filename: str):
watt_data = open(watt_data_filename).read()

aconf, ir = _get_config_and_ir(
logging.getLogger(logger_name),
watt_data)

log_errors = [rec for rec in caplog.record_tuples if rec[0] == logger_name and rec[1] > logging.INFO]

aconf_errors = aconf.errors
if "-global-" in aconf_errors:
# We expect some global errors related to us not being a real Emissary instance, such as
# "Pod labels are not mounted in the container". Ignore those.
del aconf_errors["-global-"]

return log_errors, aconf_errors

@pytest.mark.compilertest
def test_acme_privatekey_secrets():
test_data_dir = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"test_general_data"
)
def test_acme_privatekey_secrets(caplog: pytest.LogCaptureFixture):
caplog.set_level(logging.DEBUG)

test_data_file = os.path.join(test_data_dir, "test-acme-private-key-snapshot.json")
watt_data = open(test_data_file).read()
nl = "\n"
tab = "\t"

aconf, ir = _get_ir_config(watt_data)
# What this test is really about is ensuring that test-acme-private-key-snapshot.json doesn't
# emit any errors. But, in order to validate the test itself and ensure that the test is
# checking for errors in the correct place, we'll also run against a bad version of that file
# and check that we *do* see errors.

# Remember, you'll see no log output unless the test fails!
logger.debug("---- ACONF")
logger.debug(json.dumps(aconf.as_dict(), indent=2, sort_keys=True))
logger.debug("---- IR")
logger.debug(json.dumps(ir.as_dict(), indent=2, sort_keys=True))
badsnap_log_errors, badsnap_aconf_errors = _get_errors(caplog, "test_acme_privatekey_secrets-bad", os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"test_general_data",
"test-acme-private-key-snapshot-bad.json"))
assert badsnap_log_errors
assert not badsnap_aconf_errors, "Wanted no aconf errors but got:%s" % "".join([f"{nl} {err}" for err in badsnap_aconf_errors])

assert not aconf.errors, "Wanted no errors but got:\n %s" % "\n ".join(aconf.errors)
goodsnap_log_errors, goodsnap_aconf_errors = _get_errors(caplog, "test_acme_privatekey_secrets", os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"test_general_data",
"test-acme-private-key-snapshot.json"))
assert not goodsnap_log_errors, "Wanted no logged errors bug got:%s" % "".join([f"{nl} {logging.getLevelName(rec[1])}{tab}{rec[0]}:{rec[2]}" for rec in goodsnap_log_errors])
assert not goodsnap_aconf_errors, "Wanted no aconf errors but got:%s" % "".join([f"{nl} {err}" for err in goodsnap_aconf_errors])
6 changes: 4 additions & 2 deletions python/tests/unit/test_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,8 @@ def test_mappings_same_name_delta():

# loop through all the clusters in the resulting envoy config and pick out two Mappings from our test set (first and lase)
# to ensure their clusters were generated properly.
cluster1_ok, cluster2_ok = False
cluster1_ok = False
cluster2_ok = False
for cluster in econf['static_resources']['clusters']:
cname = cluster.get('name', None)
assert cname is not None, \
Expand All @@ -506,7 +507,8 @@ def test_mappings_same_name_delta():
econf = b[1]
econf = econf.as_dict()

cluster1_ok, cluster2_ok = False
cluster1_ok = False
cluster2_ok = False
for cluster in econf['static_resources']['clusters']:
cname = cluster.get('name', None)
assert cname is not None, \
Expand Down
51 changes: 0 additions & 51 deletions python/tests/unit/test_cache_data/cache_test_4.yaml
Original file line number Diff line number Diff line change
@@ -1,54 +1,4 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: bar0
---
apiVersion: v1
kind: Namespace
metadata:
name: bar1
---
apiVersion: v1
kind: Namespace
metadata:
name: bar2
---
apiVersion: v1
kind: Namespace
metadata:
name: bar3
---
apiVersion: v1
kind: Namespace
metadata:
name: bar4
---
apiVersion: v1
kind: Namespace
metadata:
name: bar5
---
apiVersion: v1
kind: Namespace
metadata:
name: bar6
---
apiVersion: v1
kind: Namespace
metadata:
name: bar7
---
apiVersion: v1
kind: Namespace
metadata:
name: bar8
---
apiVersion: v1
kind: Namespace
metadata:
name: bar9
---
apiVersion: getambassador.io/v3alpha1
kind: Mapping
metadata:
Expand Down Expand Up @@ -147,4 +97,3 @@ metadata:
spec:
prefix: /bar-9/
service: bar-9.example.com:6666