Skip to content
This repository was archived by the owner on Dec 10, 2025. It is now read-only.

Commit 2f64b96

Browse files
Patrick J. McNerthneyiciclespider
authored andcommitted
Implement unit test framework with initial unit tests.
1 parent e3bf500 commit 2f64b96

17 files changed

Lines changed: 517 additions & 197 deletions

File tree

.github/workflows/ci.yaml

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,27 +48,27 @@ jobs:
4848
# python-version: ${{ env.PYTHON_VERSION }}
4949

5050
# - name: Setup Hatch
51-
# run: pipx install hatch==1.7.0
51+
# run: pipx install hatch==1.14.1
5252

5353
# - name: Lint
5454
# run: hatch run lint:check
5555

56-
# unit-test:
57-
# runs-on: ubuntu-24.04
58-
# steps:
59-
# - name: Checkout
60-
# uses: actions/checkout@v4
56+
unit-test:
57+
runs-on: ubuntu-24.04
58+
steps:
59+
- name: Checkout
60+
uses: actions/checkout@v4
6161

62-
# - name: Setup Python
63-
# uses: actions/setup-python@v5
64-
# with:
65-
# python-version: ${{ env.PYTHON_VERSION }}
62+
- name: Setup Python
63+
uses: actions/setup-python@v5
64+
with:
65+
python-version: ${{ env.PYTHON_VERSION }}
6666

67-
# - name: Setup Hatch
68-
# run: pipx install hatch==1.7.0
67+
- name: Setup Hatch
68+
run: pipx install hatch==1.14.1
6969

70-
# - name: Run Unit Tests
71-
# run: hatch run test:unit
70+
- name: Run Unit Tests
71+
run: hatch run test:unit
7272

7373
# We want to build most packages for the amd64 and arm64 architectures. To
7474
# speed this up we build single-platform packages in parallel. We then upload

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ The following functions are provided to create Protobuf structures:
116116
| List | Create a new Protobuf list |
117117
| Yaml | Create a new Protobuf structure from a yaml string |
118118
| Json | Create a new Protobuf structure from a json string |
119+
| Base64Encode | Encode a string into base 64 |
120+
| Base64Decode | Decode a string from base 64 |
119121

120122
The following items are supported in all the Protobuf Message wrapper classes: `bool`,
121123
`len`, `contains`, `iter`, `hash`, `==`, `str`, `format`

examples/function-go-templating/inline/composition.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ spec:
2323
user = f"test-user-{ix}"
2424
r = self.resources[user]('iam.aws.upbound.io/v1beta1', 'User')
2525
r.metadata.labels['testing.upbound.io/example-name'] = user
26-
r.metadata.labels.dummy = r.observed.resource.metadata.labels.dummy or random.choice(['foo', 'bar', 'baz'])
26+
r.metadata.labels.dummy = r.observed.metadata.labels.dummy or random.choice(['foo', 'bar', 'baz'])
2727
r = self.resources[f"sample-access-key-{ix}"]('iam.aws.upbound.io/v1beta1', 'AccessKey')
2828
r.spec.forProvider.userSelector.matchLabels['testing.upbound.io/example-name'] = user
2929
r.spec.writeConnectionSecretToRef.namespace = 'crossplane.system'
Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
apiVersion: apiextensions.crossplane.io/v1
22
kind: Composition
33
metadata:
4-
name: argocds.pythonic.fortra.com
4+
name: xclusters.example.joebowbeer.com
55
spec:
66
compositeTypeRef:
7-
apiVersion: pythonic.fortra.com/v1alpha1
8-
kind: ArgoCD
7+
apiVersion: example.joebowbeer.com/v1alpha1
8+
kind: XCluster
99
mode: Pipeline
1010
pipeline:
1111
- step: pythonic
@@ -15,16 +15,41 @@ spec:
1515
apiVersion: pythonic.fn.fortra.com/v1alpha1
1616
kind: Composite
1717
composite: |
18+
def argcd_secret_config(secret):
19+
config = Map()
20+
config.tlsClientConfig.insecure = True
21+
config.tlsClientConfig.caData = B64Decode(secret.data['certificate-authority'])
22+
config.tlsClientConfig.certData = B64Decode(secret.data['client-certificate'])
23+
config.tlsClientConfig.keyData = B64Decode(secret.data['client-key'])
24+
return config
25+
1826
class Composite(BaseComposite):
1927
def compose(self):
20-
argocd = self.resources.Release('helm.crossplane.io/v1beta1', 'Release')
21-
argocd.externalName('argocd')
22-
argocd.spec.forProvider.namespace = 'argocd'
23-
argocd.spec.forProvider.chart.repository = 'https://argoproj.github.io/argo-helm'
24-
argocd.spec.forProvider.chart.name = 'argo-cd'
25-
argocd.spec.forProvider.chart.version = '8.0.7'
28+
name = self.metadata.name
29+
namespace = name
30+
31+
release = self.resources.release('helm.crossplane.io/v1beta1', 'Release', name=name)
32+
release.spec.rollbackLimit = 1
33+
release.spec.forProvider.chart.repository = 'https://charts.loft.sh'
34+
release.spec.forProvider.chart.name = 'vcluster'
35+
release.spec.forProvider.chart.version = '0.26.0'
36+
release.spec.forProvider.namespace = namespace
37+
release.spec.forProvider.values.controlPlane.proxy.extraSANs[0] = f'{name}.{namespace}'
2638
27-
# This will work once crossplane-sdk-python is updated to the V2 function api
28-
#secret = self.requireds.Secret('v1', 'Secret', 'argocd', 'argocd-secret')[0]
29-
secret = self.requireds.Secret('v1', 'Secret', labels={'app.kubernetes.io/name':'argocd-secret'})[0]
30-
self.resources.Secret('v1', 'Secret', 'default', 'argocd-secret').data = secret.data
39+
secret_name = f'vc-{name}'
40+
# This will work once crossplane-sdk-python is updated to the v2 function api
41+
#vcluster_secrets = self.requireds.Secret('v1', 'Secret', namespace, secret_name)
42+
vcluster_secrets = self.requireds.Secret('v1', 'Secret', labels={'vcluster-name':name})
43+
for secret in vcluster_secrets:
44+
if secret.metadata.name != secret_name:
45+
continue
46+
argocd_secret = self.resources.secret('v1', 'Secret', 'argocd', secret_name)
47+
argocd_secret.metadata.labels['argocd.argoproj.io/secret-type'] = 'cluster'
48+
argocd_secret.type = 'Opaque'
49+
argocd_secret.data.name = B64Encode(name)
50+
argocd_secret.data.server = B64Encode(f'https://{name}.{namespace}:443')
51+
argocd_secret.data.config = B64Encode(format(argcd_secret_config(secret), 'json'))
52+
argocd_secret.ready = argocd_secret.observed.data
53+
break
54+
else:
55+
self.ready = False

examples/helm-copy-secret/definition.yaml

Lines changed: 0 additions & 17 deletions
This file was deleted.

examples/helm-copy-secret/xr.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
apiVersion: pythonic.fortra.com/v1alpha1
2-
kind: ArgoCD
1+
apiVersion: example.joebowbeer.com/v1alpha1
2+
kind: XCluster
33
metadata:
4-
name: argocd
4+
name: xc1
55
spec: {}

function/composite.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def ready(self):
5454
def ready(self, ready):
5555
if ready:
5656
ready = fnv1.Ready.READY_TRUE
57-
elif ready == None or (isinstance(ready, function.protobuf.Values) and ready._type == function.protobuf.Values.Type.UNKNOWN):
57+
elif ready == None or (isinstance(ready, function.protobuf.Values) and ready._isUnknown):
5858
ready = fnv1.Ready.READY_UNSPECIFIED
5959
else:
6060
ready = fnv1.Ready.READY_FALSE
@@ -209,7 +209,7 @@ def ready(self):
209209
def ready(self, ready):
210210
if ready:
211211
ready = fnv1.Ready.READY_TRUE
212-
elif ready == None or (isinstance(ready, function.protobuf.Values) and ready._type == function.protobuf.Values.Type.UNKNOWN):
212+
elif ready == None or (isinstance(ready, function.protobuf.Values) and ready._isUnknown):
213213
ready = fnv1.Ready.READY_UNSPECIFIED
214214
else:
215215
ready = fnv1.Ready.READY_FALSE
@@ -415,7 +415,7 @@ def claim(self, claim):
415415
if bool(self):
416416
if claim:
417417
self._result.target = fnv1.Target.TARGET_COMPOSITE_AND_CLAIM
418-
elif claim == None or (isinstance(claim, function.protobuf.Values) and claim._type == function.protobuf.Values.Type.UNKNOWN):
418+
elif claim == None or (isinstance(claim, function.protobuf.Values) and claim._isUnknown):
419419
self._result.target = fnv1.Target.TARGET_UNSPECIFIED
420420
else:
421421
self._result.target = fnv1.Target.TARGET_COMPOSITE
@@ -502,7 +502,7 @@ def status(self, status):
502502
condition.status = fnv1.Status.STATUS_CONDITION_TRUE
503503
elif status == None:
504504
condition.status = fnv1.Status.STATUS_CONDITION_UNKNOWN
505-
elif isinstance(ready, function.protobuf.Values) and ready._type == function.protobuf.Values.Type.UNKNOWN:
505+
elif isinstance(status, function.protobuf.Values) and status._isUnknown:
506506
condition.status = fnv1.Status.STATUS_CONDITION_UNSPECIFIED
507507
else:
508508
condition.status = fnv1.Status.STATUS_CONDITION_FALSE
@@ -549,7 +549,7 @@ def claim(self, claim):
549549
condition = self._find_condition(True)
550550
if claim:
551551
condition.target = fnv1.Target.TARGET_COMPOSITE_AND_CLAIM
552-
elif claim == None or (isinstance(claim, function.protobuf.Values) and claim._type == function.protobuf.Values.Type.UNKNOWN):
552+
elif claim == None or (isinstance(claim, function.protobuf.Values) and claim._isUnknown):
553553
condition.target = fnv1.Target.TARGET_UNSPECIFIED
554554
else:
555555
condition.target = fnv1.Target.TARGET_COMPOSITE

0 commit comments

Comments
 (0)