Skip to content

Commit 6b71f34

Browse files
committed
Adds tests for notification bus
1 parent 9b72000 commit 6b71f34

7 files changed

Lines changed: 329 additions & 1 deletion

test/functional/base_test.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,9 @@ func NovaConductorConditionGetter(name types.NamespacedName) condition.Condition
218218

219219
func CreateNovaMessageBusSecret(cell CellNames) *corev1.Secret {
220220
s := th.CreateSecret(
221-
types.NamespacedName{Namespace: cell.CellCRName.Namespace, Name: fmt.Sprintf("%s-secret", cell.TransportURLName.Name)},
221+
types.NamespacedName{
222+
Namespace: cell.CellCRName.Namespace,
223+
Name: fmt.Sprintf("%s-secret", cell.TransportURLName.Name)},
222224
map[string][]byte{
223225
"transport_url": []byte(fmt.Sprintf("rabbit://%s/fake", cell.CellName)),
224226
},
@@ -227,6 +229,20 @@ func CreateNovaMessageBusSecret(cell CellNames) *corev1.Secret {
227229
return s
228230
}
229231

232+
func CreateNotificiationTransportURLSecret(notificationsBus NotificationsBusNames) *corev1.Secret {
233+
s := th.CreateSecret(
234+
types.NamespacedName{
235+
Namespace: novaNames.NovaName.Namespace,
236+
// Name: fmt.Sprintf("%s-secret", notificationsBus.TransportURLName.Name)},
237+
Name: fmt.Sprintf("%s-secret", notificationsBus.BusName)},
238+
map[string][]byte{
239+
"transport_url": []byte(fmt.Sprintf("rabbit://%s/fake", notificationsBus.TransportURLName.Name)),
240+
},
241+
)
242+
logger.Info("Secret created", "name", s.Name)
243+
return s
244+
}
245+
230246
func GetDefaultNovaCellSpec(cell CellNames) map[string]interface{} {
231247
return map[string]interface{}{
232248
"cellName": cell.CellName,
@@ -474,6 +490,20 @@ func GetCellNames(novaName types.NamespacedName, cell string) CellNames {
474490
return c
475491
}
476492

493+
type NotificationsBusNames struct {
494+
BusName string
495+
TransportURLName types.NamespacedName
496+
}
497+
498+
func GetNotificationsBusNames(novaName types.NamespacedName) NotificationsBusNames {
499+
return NotificationsBusNames{
500+
BusName: "rabbitmq-broadcaster",
501+
TransportURLName: types.NamespacedName{
502+
Namespace: novaName.Namespace,
503+
Name: novaName.Name + "-notification-transport"},
504+
}
505+
}
506+
477507
type NovaNames struct {
478508
Namespace string
479509
NovaName types.NamespacedName

test/functional/nova_compute_ironic_controller_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,34 @@ var _ = Describe("NovaCompute controller", func() {
139139

140140
})
141141

142+
When("the Secret is created but notification fields is missing", func() {
143+
BeforeEach(func() {
144+
secret := &corev1.Secret{
145+
ObjectMeta: metav1.ObjectMeta{
146+
Name: cell1.InternalCellSecretName.Name,
147+
Namespace: cell1.InternalCellSecretName.Namespace,
148+
},
149+
Data: map[string][]byte{
150+
"ServicePassword": []byte("12345678"),
151+
"transport_url": []byte("rabbit://cell1/fake"),
152+
// notification_transport_url is missing
153+
},
154+
}
155+
Expect(k8sClient.Create(ctx, secret)).Should(Succeed())
156+
DeferCleanup(k8sClient.Delete, ctx, secret)
157+
})
158+
159+
It("is not Ready", func() {
160+
th.ExpectCondition(
161+
cell1.NovaComputeName,
162+
ConditionGetterFunc(NovaComputeConditionGetter),
163+
condition.ReadyCondition,
164+
corev1.ConditionFalse,
165+
)
166+
})
167+
168+
})
169+
142170
When("the Secret is created with all the expected fields", func() {
143171
BeforeEach(func() {
144172
DeferCleanup(

test/functional/nova_controller_test.go

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,151 @@ import (
3838
"github.com/openstack-k8s-operators/nova-operator/controllers"
3939
)
4040

41+
var _ = Describe("Nova controller - notifications", func() {
42+
43+
When("Nova CR instance is created", func() {
44+
BeforeEach(func() {
45+
DeferCleanup(
46+
k8sClient.Delete, ctx, CreateNovaSecret(novaNames.NovaName.Namespace, SecretName))
47+
DeferCleanup(
48+
k8sClient.Delete, ctx, CreateNovaMessageBusSecret(cell0))
49+
DeferCleanup(
50+
mariadb.DeleteDBService,
51+
mariadb.CreateDBService(
52+
novaNames.NovaName.Namespace,
53+
"openstack",
54+
corev1.ServiceSpec{
55+
Ports: []corev1.ServicePort{{Port: 3306}},
56+
},
57+
),
58+
)
59+
memcachedSpec := infra.GetDefaultMemcachedSpec()
60+
61+
DeferCleanup(infra.DeleteMemcached, infra.CreateMemcached(novaNames.NovaName.Namespace, MemcachedInstance, memcachedSpec))
62+
infra.SimulateMemcachedReady(novaNames.MemcachedNamespace)
63+
64+
DeferCleanup(keystone.DeleteKeystoneAPI, keystone.CreateKeystoneAPI(novaNames.NovaName.Namespace))
65+
66+
DeferCleanup(th.DeleteInstance, CreateNovaWithCell0(novaNames.NovaName))
67+
68+
keystone.SimulateKeystoneServiceReady(novaNames.KeystoneServiceName)
69+
mariadb.SimulateMariaDBDatabaseCompleted(novaNames.APIMariaDBDatabaseName)
70+
mariadb.SimulateMariaDBAccountCompleted(novaNames.APIMariaDBDatabaseAccount)
71+
mariadb.SimulateMariaDBDatabaseCompleted(cell0.MariaDBDatabaseName)
72+
mariadb.SimulateMariaDBAccountCompleted(cell0.MariaDBAccountName)
73+
infra.SimulateTransportURLReady(cell0.TransportURLName)
74+
SimulateReadyOfNovaTopServices()
75+
})
76+
It("notification transport url is not set", func() {
77+
78+
// assert that a the top level internal internal secret is created
79+
// with the proper data
80+
internalTopLevelSecret := th.GetSecret(novaNames.InternalTopLevelSecretName)
81+
// verify if nova secret has notification-transport-url
82+
Expect(internalTopLevelSecret.Data).To(HaveKey("notification_transport_url"))
83+
Expect(internalTopLevelSecret.Data).To(
84+
HaveKeyWithValue("notification_transport_url", []byte("")))
85+
86+
assertNotHaveNotificationTransportURL := func(configData string) {
87+
88+
Expect(configData).ToNot(
89+
ContainSubstring("[notifications]"))
90+
91+
Expect(configData).To(
92+
ContainSubstring("[oslo_messaging_notifications]\ndriver = noop"))
93+
94+
}
95+
96+
// verify if confs are updated with notification-transport-url under oslo_messaging_notifications
97+
// assert in nova-api conf
98+
configDataMap := th.GetSecret(novaNames.APIConfigDataName)
99+
Expect(configDataMap.Data).Should(HaveKey("01-nova.conf"))
100+
configData := string(configDataMap.Data["01-nova.conf"])
101+
assertNotHaveNotificationTransportURL(configData)
102+
103+
// assert in sch conf
104+
configDataMap = th.GetSecret(novaNames.SchedulerConfigDataName)
105+
Expect(configDataMap.Data).Should(HaveKey("01-nova.conf"))
106+
configData = string(configDataMap.Data["01-nova.conf"])
107+
assertNotHaveNotificationTransportURL(configData)
108+
109+
// assert in cell0-conductor conf
110+
configDataMap = th.GetSecret(cell0.ConductorConfigDataName)
111+
Expect(configDataMap.Data).Should(HaveKey("01-nova.conf"))
112+
configData = string(configDataMap.Data["01-nova.conf"])
113+
assertNotHaveNotificationTransportURL(configData)
114+
115+
})
116+
117+
It("notification transport url is set with new rabbit", func() {
118+
119+
// add new-rabbit in Nova CR
120+
notificationsBus := GetNotificationsBusNames(novaNames.NovaName)
121+
DeferCleanup(k8sClient.Delete, ctx, CreateNotificiationTransportURLSecret(notificationsBus))
122+
123+
Eventually(func(g Gomega) {
124+
nova := GetNova(novaNames.NovaName)
125+
nova.Spec.NotificationsBusInstance = &notificationsBus.BusName
126+
g.Expect(k8sClient.Update(ctx, nova)).Should(Succeed())
127+
}, timeout, interval).Should(Succeed())
128+
129+
// as new-rabbit already exists in cluster, infra operator will create transporturl for it
130+
// simulating same
131+
infra.SimulateTransportURLReady(notificationsBus.TransportURLName)
132+
transportURLName := infra.GetTransportURL(notificationsBus.TransportURLName)
133+
Expect(transportURLName.Spec.RabbitmqClusterName).To(Equal(notificationsBus.BusName))
134+
135+
th.ExpectCondition(
136+
novaNames.NovaName,
137+
ConditionGetterFunc(NovaConditionGetter),
138+
novav1.NovaNotificationMQReadyCondition,
139+
corev1.ConditionTrue,
140+
)
141+
142+
// the nova secret(i.e top level secret) should have notification_transport_url value set
143+
internalTopLevelSecret := th.GetSecret(novaNames.InternalTopLevelSecretName)
144+
Expect(internalTopLevelSecret.Data).To(HaveKey("notification_transport_url"))
145+
Expect(internalTopLevelSecret.Data["notification_transport_url"]).ShouldNot(BeEmpty())
146+
147+
assertHaveNotificationTransportURL := func(configData string) {
148+
149+
expectedConf1 := "[notifications]\nnotify_on_state_change = vm_and_task_state\nnotification_format=both"
150+
151+
expectedConf2 := fmt.Sprintf(
152+
"[oslo_messaging_notifications]\ntransport_url = rabbit://%s/fake\ndriver = messagingv2",
153+
notificationsBus.TransportURLName.Name)
154+
155+
Expect(configData).To(
156+
ContainSubstring(expectedConf1))
157+
158+
Expect(configData).To(
159+
ContainSubstring(expectedConf2))
160+
161+
}
162+
163+
// assert in nova-api conf
164+
configDataMap := th.GetSecret(novaNames.APIConfigDataName)
165+
Expect(configDataMap.Data).Should(HaveKey("01-nova.conf"))
166+
configData := string(configDataMap.Data["01-nova.conf"])
167+
assertHaveNotificationTransportURL(configData)
168+
169+
// assert in sch conf
170+
configDataMap = th.GetSecret(novaNames.SchedulerConfigDataName)
171+
Expect(configDataMap.Data).Should(HaveKey("01-nova.conf"))
172+
configData = string(configDataMap.Data["01-nova.conf"])
173+
assertHaveNotificationTransportURL(configData)
174+
175+
// assert in cell0-conductor conf
176+
configDataMap = th.GetSecret(cell0.ConductorConfigDataName)
177+
Expect(configDataMap.Data).Should(HaveKey("01-nova.conf"))
178+
configData = string(configDataMap.Data["01-nova.conf"])
179+
assertHaveNotificationTransportURL(configData)
180+
181+
})
182+
})
183+
184+
})
185+
41186
var _ = Describe("Nova controller", func() {
42187
When("Nova CR instance is created without a proper secret", func() {
43188
BeforeEach(func() {

test/functional/nova_scheduler_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,42 @@ var _ = Describe("NovaScheduler controller", func() {
163163
})
164164
})
165165

166+
When("the Secret is created but notification fields is missing", func() {
167+
BeforeEach(func() {
168+
secret := &corev1.Secret{
169+
ObjectMeta: metav1.ObjectMeta{
170+
Name: novaNames.InternalTopLevelSecretName.Name,
171+
Namespace: novaNames.InternalTopLevelSecretName.Namespace,
172+
},
173+
Data: map[string][]byte{
174+
"ServicePassword": []byte("12345678"),
175+
"transport_url": []byte("rabbit://api/fake"),
176+
// notification_transport_url is missing
177+
},
178+
}
179+
Expect(k8sClient.Create(ctx, secret)).Should(Succeed())
180+
DeferCleanup(k8sClient.Delete, ctx, secret)
181+
})
182+
183+
It("is not Ready", func() {
184+
th.ExpectCondition(
185+
novaNames.SchedulerName,
186+
ConditionGetterFunc(NovaSchedulerConditionGetter),
187+
condition.ReadyCondition,
188+
corev1.ConditionFalse,
189+
)
190+
})
191+
192+
It("reports that the inputs are not ready", func() {
193+
th.ExpectCondition(
194+
novaNames.SchedulerName,
195+
ConditionGetterFunc(NovaSchedulerConditionGetter),
196+
condition.InputReadyCondition,
197+
corev1.ConditionFalse,
198+
)
199+
})
200+
})
201+
166202
When("the Secret is created with all the expected fields", func() {
167203
BeforeEach(func() {
168204
DeferCleanup(

test/functional/novaapi_controller_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,42 @@ var _ = Describe("NovaAPI controller", func() {
162162
})
163163
})
164164

165+
When("the Secret is created but notification_transport_url field is missing", func() {
166+
BeforeEach(func() {
167+
secret := &corev1.Secret{
168+
ObjectMeta: metav1.ObjectMeta{
169+
Name: novaNames.InternalTopLevelSecretName.Name,
170+
Namespace: novaNames.InternalTopLevelSecretName.Namespace,
171+
},
172+
Data: map[string][]byte{
173+
"ServicePassword": []byte("12345678"),
174+
"transport_url": []byte("rabbit://api/fake"),
175+
// notification_transport_url is missing
176+
},
177+
}
178+
Expect(k8sClient.Create(ctx, secret)).Should(Succeed())
179+
DeferCleanup(k8sClient.Delete, ctx, secret)
180+
})
181+
182+
It("is not Ready", func() {
183+
th.ExpectCondition(
184+
novaNames.APIName,
185+
ConditionGetterFunc(NovaAPIConditionGetter),
186+
condition.ReadyCondition,
187+
corev1.ConditionFalse,
188+
)
189+
})
190+
191+
It("reports that the inputs are not ready", func() {
192+
th.ExpectCondition(
193+
novaNames.APIName,
194+
ConditionGetterFunc(NovaAPIConditionGetter),
195+
condition.InputReadyCondition,
196+
corev1.ConditionFalse,
197+
)
198+
})
199+
})
200+
165201
When("the Secret is created with all the expected fields", func() {
166202
BeforeEach(func() {
167203
DeferCleanup(

test/functional/novacell_controller_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,10 +303,27 @@ var _ = Describe("NovaCell controller", func() {
303303
corev1.ConditionTrue,
304304
)
305305

306+
assertHaveNotificationTransportURL := func(configData string) {
307+
308+
expectedConf1 := "[notifications]\nnotify_on_state_change = vm_and_task_state\nnotification_format=both"
309+
310+
expectedConf2 := fmt.Sprintf(
311+
"[oslo_messaging_notifications]\ntransport_url = rabbit://notifications/fake\ndriver = messagingv2")
312+
313+
Expect(configData).To(
314+
ContainSubstring(expectedConf1))
315+
316+
Expect(configData).To(
317+
ContainSubstring(expectedConf2))
318+
319+
}
320+
306321
computeConfigData := th.GetSecret(cell1.ComputeConfigSecretName)
307322
Expect(computeConfigData).ShouldNot(BeNil())
308323
Expect(computeConfigData.Data).Should(HaveKey("01-nova.conf"))
309324
configData := string(computeConfigData.Data["01-nova.conf"])
325+
326+
assertHaveNotificationTransportURL(configData)
310327
// ensure we maintain the tripleo default for backwards compatibility
311328
Expect(configData).Should(ContainSubstring("dhcp_domain = ''"))
312329
Expect(configData).To(ContainSubstring("transport_url=rabbit://cell1/fake"))

test/functional/novaconductor_controller_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,42 @@ var _ = Describe("NovaConductor controller", func() {
162162
})
163163
})
164164

165+
When("the Secret is created but notification fields is missing", func() {
166+
BeforeEach(func() {
167+
secret := &corev1.Secret{
168+
ObjectMeta: metav1.ObjectMeta{
169+
Name: cell0.InternalCellSecretName.Name,
170+
Namespace: cell0.InternalCellSecretName.Namespace,
171+
},
172+
Data: map[string][]byte{
173+
"ServicePassword": []byte("12345678"),
174+
"transport_url": []byte("rabbit://cell0/fake"),
175+
// notification_transport_url is missing
176+
},
177+
}
178+
Expect(k8sClient.Create(ctx, secret)).Should(Succeed())
179+
DeferCleanup(k8sClient.Delete, ctx, secret)
180+
})
181+
182+
It("is not Ready", func() {
183+
th.ExpectCondition(
184+
cell0.ConductorName,
185+
ConditionGetterFunc(NovaConductorConditionGetter),
186+
condition.ReadyCondition,
187+
corev1.ConditionFalse,
188+
)
189+
})
190+
191+
It("reports that the inputs are not ready", func() {
192+
th.ExpectCondition(
193+
cell0.ConductorName,
194+
ConditionGetterFunc(NovaConductorConditionGetter),
195+
condition.InputReadyCondition,
196+
corev1.ConditionFalse,
197+
)
198+
})
199+
})
200+
165201
When("the Secret is created with all the expected fields", func() {
166202
BeforeEach(func() {
167203
DeferCleanup(

0 commit comments

Comments
 (0)