Skip to content

Commit c92d64b

Browse files
committed
Add tests for PublicViewer
Signed-off-by: Francesco Ilario <filario@redhat.com>
1 parent 0b43c07 commit c92d64b

7 files changed

Lines changed: 350 additions & 38 deletions

File tree

make/test.mk

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ E2E_PARALLELISM=1
3838

3939
TESTS_RUN_FILTER_REGEXP ?= ""
4040

41+
.PHONY: test-e2e-community
42+
test-e2e-community: prepare-e2e deploy-e2e e2e-run-community
43+
@:
44+
45+
.PHONY: test-e2e-community-local
46+
test-e2e-community-local: prepare-e2e deploy-e2e-local e2e-run-community
47+
@:
48+
4149
.PHONY: test-e2e
4250
## Run the e2e tests
4351
test-e2e: INSTALL_OPERATOR=true
@@ -116,15 +124,33 @@ test-e2e-registration-local:
116124
.PHONY: e2e-run-parallel
117125
e2e-run-parallel:
118126
@echo "Running e2e tests in parallel..."
127+
oc patch -n ${HOST_NS} toolchainconfigs.toolchain.dev.openshift.com config --patch='{"spec":{"global":{"publicViewer":{"enabled":false}}}}' --type=merge
128+
oc delete -n ${HOST_NS} pods -l control-plane=controller-manager
129+
oc delete -n ${HOST_NS} pod -l name=registration-service
130+
oc rollout -n ${HOST_NS} status deployment
119131
$(MAKE) execute-tests MEMBER_NS=${MEMBER_NS} MEMBER_NS_2=${MEMBER_NS_2} HOST_NS=${HOST_NS} REGISTRATION_SERVICE_NS=${REGISTRATION_SERVICE_NS} TESTS_TO_EXECUTE="./test/e2e/parallel" E2E_PARALLELISM=100
120132
@echo "The parallel e2e tests successfully finished"
121133

122134
.PHONY: e2e-run
123135
e2e-run:
124136
@echo "Running e2e tests..."
137+
oc patch -n ${HOST_NS} toolchainconfigs.toolchain.dev.openshift.com config --patch='{"spec":{"global":{"publicViewer":{"enabled":false}}}}' --type=merge
138+
oc delete -n ${HOST_NS} pods -l control-plane=controller-manager
139+
oc delete -n ${HOST_NS} pod -l name=registration-service
140+
oc rollout -n ${HOST_NS} status deployment
125141
$(MAKE) execute-tests MEMBER_NS=${MEMBER_NS} MEMBER_NS_2=${MEMBER_NS_2} HOST_NS=${HOST_NS} REGISTRATION_SERVICE_NS=${REGISTRATION_SERVICE_NS} TESTS_TO_EXECUTE="./test/e2e ./test/metrics"
126142
@echo "The e2e tests successfully finished"
127143

144+
.PHONY: e2e-run-community
145+
e2e-run-community:
146+
@echo "Running e2e community tests..."
147+
oc patch -n ${HOST_NS} toolchainconfigs.toolchain.dev.openshift.com config --patch='{"spec":{"global":{"publicViewer":{"enabled":true,"username":"public-viewer"}}}}' --type=merge
148+
oc delete -n ${HOST_NS} pods -l control-plane=controller-manager
149+
oc delete -n ${HOST_NS} pod -l name=registration-service
150+
oc rollout -n ${HOST_NS} status deployment
151+
$(MAKE) execute-tests MEMBER_NS=${MEMBER_NS} MEMBER_NS_2=${MEMBER_NS_2} HOST_NS=${HOST_NS} REGISTRATION_SERVICE_NS=${REGISTRATION_SERVICE_NS} TESTS_TO_EXECUTE="./test/e2e/community"
152+
@echo "The e2e community tests successfully finished"
153+
128154
.PHONY: execute-tests
129155
execute-tests:
130156
@echo "Present Spaces"

test/e2e/community/proxy_test.go

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
package community_test
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/gofrs/uuid"
8+
"github.com/stretchr/testify/require"
9+
10+
corev1 "k8s.io/api/core/v1"
11+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12+
"k8s.io/apimachinery/pkg/labels"
13+
"k8s.io/apimachinery/pkg/selection"
14+
waitpoll "k8s.io/apimachinery/pkg/util/wait"
15+
"sigs.k8s.io/controller-runtime/pkg/client"
16+
17+
toolchainv1alpha1 "github.com/codeready-toolchain/api/api/v1alpha1"
18+
commonauth "github.com/codeready-toolchain/toolchain-common/pkg/test/auth"
19+
. "github.com/codeready-toolchain/toolchain-e2e/testsupport"
20+
authsupport "github.com/codeready-toolchain/toolchain-e2e/testsupport/auth"
21+
"github.com/codeready-toolchain/toolchain-e2e/testsupport/spacebinding"
22+
"github.com/codeready-toolchain/toolchain-e2e/testsupport/tiers"
23+
"github.com/codeready-toolchain/toolchain-e2e/testsupport/wait"
24+
)
25+
26+
type proxyUser struct {
27+
expectedMemberCluster *wait.MemberAwaitility
28+
username string
29+
token string
30+
identityID uuid.UUID
31+
signup *toolchainv1alpha1.UserSignup
32+
compliantUsername string
33+
}
34+
35+
// tests access to community-shared spaces
36+
func TestPublicViewerProxy(t *testing.T) {
37+
// given
38+
39+
// make sure everything is ready before running the actual tests
40+
awaitilities := WaitForDeployments(t)
41+
hostAwait := awaitilities.Host()
42+
memberAwait := awaitilities.Member1()
43+
// we create a space to share , a new MUR and a SpaceBindingRequest
44+
space, _, _ := NewSpaceBindingRequest(t, awaitilities, memberAwait, hostAwait, "admin")
45+
46+
communityUser := &proxyUser{
47+
expectedMemberCluster: memberAwait,
48+
username: "community-user",
49+
identityID: uuid.Must(uuid.NewV4()),
50+
}
51+
createAppStudioUser(t, awaitilities, communityUser)
52+
53+
communityUserProxyClient, err := hostAwait.CreateAPIProxyClient(t, communityUser.token, hostAwait.APIProxyURL)
54+
require.NoError(t, err)
55+
56+
t.Run("space is flagged as community", func(t *testing.T) {
57+
// when
58+
sb := CreateCommunitySpaceBinding(t, hostAwait, space.Name, space.Namespace)
59+
require.NoError(t, err)
60+
t.Logf("created space binding for public-viewer:\n%+v", sb)
61+
62+
// Wait until space is flagged as community
63+
require.NoError(t,
64+
waitpoll.Poll(hostAwait.RetryInterval, hostAwait.Timeout, func() (bool, error) {
65+
mr, err := labels.NewRequirement(toolchainv1alpha1.SpaceBindingMasterUserRecordLabelKey, selection.In, []string{"public-viewer"})
66+
if err != nil {
67+
return false, err
68+
}
69+
70+
sr, err := labels.NewRequirement(toolchainv1alpha1.SpaceBindingSpaceLabelKey, selection.Equals, []string{space.Name})
71+
if err != nil {
72+
return false, err
73+
}
74+
75+
opts := &client.ListOptions{
76+
Namespace: space.Namespace,
77+
LabelSelector: labels.NewSelector().Add(*sr, *mr),
78+
}
79+
sbs := &toolchainv1alpha1.SpaceBindingList{}
80+
if err := hostAwait.Client.List(context.TODO(), sbs, opts); err != nil {
81+
return false, err
82+
}
83+
84+
return len(sbs.Items) == 1, nil
85+
}))
86+
87+
sp := toolchainv1alpha1.Space{}
88+
err = hostAwait.Client.Get(context.TODO(), client.ObjectKeyFromObject(space), &sp)
89+
require.NoError(t, err)
90+
91+
/*
92+
Given Space exists for user A
93+
Given User community-user exists
94+
When A flags their space visibility to "community"
95+
Then community-user can view A's Space
96+
And community-user cannot create resources in A's Space
97+
*/
98+
t.Run("community user access to community space", func(t *testing.T) {
99+
require.NotEmpty(t, sp.Status.ProvisionedNamespaces)
100+
101+
t.Run("community user can list config maps from community space", func(t *testing.T) {
102+
// then
103+
cms := corev1.ConfigMapList{}
104+
105+
communityUserProxyClient, err := hostAwait.CreateAPIProxyClient(t, communityUser.token, hostAwait.ProxyURLWithWorkspaceContext(sp.Name))
106+
require.NoError(t, err)
107+
108+
err = communityUserProxyClient.List(context.TODO(), &cms, client.InNamespace(sp.Status.ProvisionedNamespaces[0].Name))
109+
require.NoError(t, err)
110+
})
111+
112+
t.Run("community user cannot create config maps into space", func(t *testing.T) {
113+
cm := corev1.ConfigMap{
114+
ObjectMeta: metav1.ObjectMeta{
115+
Name: "test-cm",
116+
Namespace: sp.Status.ProvisionedNamespaces[0].Name,
117+
},
118+
}
119+
err := communityUserProxyClient.Create(context.TODO(), &cm)
120+
require.Error(t, err)
121+
})
122+
})
123+
124+
/*
125+
Given Space exists for user A
126+
Given SSO user joe exists
127+
When A flags their space visibility to "community"
128+
Then joe can view A's Space
129+
And joe cannot create resources in A's Space
130+
*/
131+
t.Run("as sso user", func(t *testing.T) {
132+
// Given
133+
userIdentity := &commonauth.Identity{
134+
ID: uuid.Must(uuid.NewV4()),
135+
Username: "joe",
136+
}
137+
claims := []commonauth.ExtraClaim{commonauth.WithEmailClaim("joe@joe.joe")}
138+
token, err := authsupport.NewTokenFromIdentity(userIdentity, claims...)
139+
require.NoError(t, err)
140+
141+
joeCli, err := hostAwait.CreateAPIProxyClient(t, token, hostAwait.ProxyURLWithWorkspaceContext(sp.Name))
142+
require.NoError(t, err)
143+
144+
t.Run("sso user can list config maps from space", func(t *testing.T) {
145+
// then
146+
cms := corev1.ConfigMapList{}
147+
err := joeCli.List(context.TODO(), &cms, client.InNamespace(sp.Status.ProvisionedNamespaces[0].Name))
148+
require.NoError(t, err)
149+
})
150+
151+
t.Run("sso user cannot create config maps into space", func(t *testing.T) {
152+
// then
153+
cm := corev1.ConfigMap{
154+
ObjectMeta: metav1.ObjectMeta{
155+
Name: "test-cm",
156+
Namespace: sp.Status.ProvisionedNamespaces[0].Name,
157+
},
158+
}
159+
err := joeCli.Create(context.TODO(), &cm)
160+
require.Error(t, err)
161+
})
162+
})
163+
})
164+
}
165+
166+
func createAppStudioUser(t *testing.T, awaitilities wait.Awaitilities, user *proxyUser) {
167+
// Create and approve signup
168+
req := NewSignupRequest(awaitilities).
169+
Username(user.username).
170+
IdentityID(user.identityID).
171+
ManuallyApprove().
172+
TargetCluster(user.expectedMemberCluster).
173+
EnsureMUR().
174+
RequireConditions(wait.ConditionSet(wait.Default(), wait.ApprovedByAdmin())...).
175+
Execute(t)
176+
user.signup, _ = req.Resources()
177+
user.token = req.GetToken()
178+
tiers.MoveSpaceToTier(t, awaitilities.Host(), user.signup.Status.CompliantUsername, "appstudio")
179+
VerifyResourcesProvisionedForSignup(t, awaitilities, user.signup, "deactivate30", "appstudio")
180+
user.compliantUsername = user.signup.Status.CompliantUsername
181+
_, err := awaitilities.Host().WaitForMasterUserRecord(t, user.compliantUsername, wait.UntilMasterUserRecordHasCondition(wait.Provisioned()))
182+
require.NoError(t, err)
183+
}
184+
185+
func CreateCommunitySpaceBinding(
186+
t *testing.T,
187+
hostAwait *wait.HostAwaitility,
188+
spaceName, spaceNamespace string,
189+
) *toolchainv1alpha1.SpaceBinding {
190+
return spacebinding.CreateSpaceBindingStr(t, hostAwait, "public-viewer", spaceName, spaceNamespace, "contributor")
191+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package community_test
2+
3+
import (
4+
"sort"
5+
"testing"
6+
7+
"github.com/gofrs/uuid"
8+
"github.com/stretchr/testify/require"
9+
10+
"k8s.io/apimachinery/pkg/types"
11+
12+
toolchainv1alpha1 "github.com/codeready-toolchain/api/api/v1alpha1"
13+
14+
testspace "github.com/codeready-toolchain/toolchain-common/pkg/test/space"
15+
spacebindingrequesttestcommon "github.com/codeready-toolchain/toolchain-common/pkg/test/spacebindingrequest"
16+
. "github.com/codeready-toolchain/toolchain-e2e/testsupport"
17+
testsupportspace "github.com/codeready-toolchain/toolchain-e2e/testsupport/space"
18+
"github.com/codeready-toolchain/toolchain-e2e/testsupport/spacebinding"
19+
"github.com/codeready-toolchain/toolchain-e2e/testsupport/wait"
20+
)
21+
22+
func NewSpaceBindingRequest(
23+
t *testing.T,
24+
awaitilities wait.Awaitilities,
25+
memberAwait *wait.MemberAwaitility,
26+
hostAwait *wait.HostAwaitility,
27+
spaceRole string,
28+
) (
29+
*toolchainv1alpha1.Space,
30+
*toolchainv1alpha1.SpaceBindingRequest,
31+
*toolchainv1alpha1.SpaceBinding,
32+
) {
33+
space, firstUserSignup, _ := testsupportspace.CreateSpace(t, awaitilities, testspace.WithTierName("appstudio"), testspace.WithSpecTargetCluster(memberAwait.ClusterName))
34+
// wait for the namespace to be provisioned since we will be creating the SpaceBindingRequest into it.
35+
space, err := hostAwait.WaitForSpace(t, space.Name, wait.UntilSpaceHasAnyProvisionedNamespaces())
36+
require.NoError(t, err)
37+
// let's create a new MUR that will have access to the space
38+
username := uuid.Must(uuid.NewV4()).String()
39+
_, secondUserMUR := NewSignupRequest(awaitilities).
40+
Username(username).
41+
Email(username + "@acme.com").
42+
ManuallyApprove().
43+
TargetCluster(memberAwait).
44+
RequireConditions(wait.ConditionSet(wait.Default(), wait.ApprovedByAdmin())...).
45+
NoSpace().
46+
WaitForMUR().Execute(t).Resources()
47+
// create the spacebinding request
48+
spaceBindingRequest := spacebinding.CreateSpaceBindingRequest(t, awaitilities, memberAwait.ClusterName,
49+
spacebinding.WithSpecSpaceRole(spaceRole),
50+
51+
spacebinding.WithSpecMasterUserRecord(secondUserMUR.GetName()),
52+
spacebinding.WithNamespace(testsupportspace.GetDefaultNamespace(space.Status.ProvisionedNamespaces)),
53+
)
54+
55+
// then
56+
// check for the spaceBinding creation
57+
spaceBinding, err := hostAwait.WaitForSpaceBinding(t, spaceBindingRequest.Spec.MasterUserRecord, space.Name,
58+
wait.UntilSpaceBindingHasMurName(spaceBindingRequest.Spec.MasterUserRecord),
59+
wait.UntilSpaceBindingHasSpaceName(space.Name),
60+
wait.UntilSpaceBindingHasSpaceRole(spaceBindingRequest.Spec.SpaceRole),
61+
wait.UntilSpaceBindingHasLabel(toolchainv1alpha1.SpaceBindingRequestLabelKey, spaceBindingRequest.GetName()),
62+
wait.UntilSpaceBindingHasLabel(toolchainv1alpha1.SpaceBindingRequestNamespaceLabelKey, spaceBindingRequest.GetNamespace()),
63+
)
64+
require.NoError(t, err)
65+
// wait for spacebinding request status
66+
spaceBindingRequest, err = memberAwait.WaitForSpaceBindingRequest(t, types.NamespacedName{Namespace: spaceBindingRequest.GetNamespace(), Name: spaceBindingRequest.GetName()},
67+
wait.UntilSpaceBindingRequestHasConditions(spacebindingrequesttestcommon.Ready()),
68+
)
69+
require.NoError(t, err)
70+
tier, err := awaitilities.Host().WaitForNSTemplateTier(t, space.Spec.TierName)
71+
require.NoError(t, err)
72+
if spaceRole == "admin" {
73+
usernamesSorted := []string{firstUserSignup.Status.CompliantUsername, secondUserMUR.Name}
74+
sort.Strings(usernamesSorted)
75+
_, err = memberAwait.WaitForNSTmplSet(t, space.Name,
76+
wait.UntilNSTemplateSetHasSpaceRoles(
77+
wait.SpaceRole(tier.Spec.SpaceRoles[spaceRole].TemplateRef, usernamesSorted[0], usernamesSorted[1])))
78+
require.NoError(t, err)
79+
} else {
80+
_, err = memberAwait.WaitForNSTmplSet(t, space.Name,
81+
wait.UntilNSTemplateSetHasSpaceRoles(
82+
wait.SpaceRole(tier.Spec.SpaceRoles["admin"].TemplateRef, firstUserSignup.Status.CompliantUsername),
83+
wait.SpaceRole(tier.Spec.SpaceRoles[spaceRole].TemplateRef, secondUserMUR.Name)))
84+
require.NoError(t, err)
85+
}
86+
testsupportspace.VerifyResourcesProvisionedForSpace(t, awaitilities, space.Name)
87+
return space, spaceBindingRequest, spaceBinding
88+
}

0 commit comments

Comments
 (0)