1 # Copyright 2021 Canonical Ltd.
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 # not use this file except in compliance with the License. You may obtain
5 # a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations
15 # For those usages not covered by the Apache License, Version 2.0 please
16 # contact: legal@canonical.com
20 from ops
import pebble
21 from ops
.model
import ActiveStatus
, BlockedStatus
22 from ops
.testing
import Harness
23 from pytest_mock
import MockerFixture
25 from charm
import FERNET_KEY_REPOSITORY
, KEYSTONE_FOLDER
, KeystoneCharm
29 def harness_no_relations(mocker
: MockerFixture
):
30 mocker
.patch("charm.cluster")
31 mocker
.patch("charm.KubernetesServicePatch")
32 keystone_harness
= Harness(KeystoneCharm
)
33 keystone_harness
.begin()
34 container
= keystone_harness
.charm
.unit
.get_container("keystone")
35 keystone_harness
.set_can_connect(container
, True)
36 container
.make_dir(KEYSTONE_FOLDER
, make_parents
=True)
37 container
.make_dir(FERNET_KEY_REPOSITORY
, make_parents
=True)
38 container
.push(f
"{FERNET_KEY_REPOSITORY}0", "token")
39 container
.make_dir("/app", make_parents
=True)
40 container
.push("/app/start.sh", "")
41 container
.exec = mocker
.Mock()
42 yield keystone_harness
43 keystone_harness
.cleanup()
47 def harness(harness_no_relations
: Harness
):
48 mysql_rel_id
= harness_no_relations
.add_relation("db", "mysql")
49 harness_no_relations
.add_relation_unit(mysql_rel_id
, "mysql/0")
50 harness_no_relations
.update_relation_data(
57 "root_password": "root_pass",
58 "password": "password",
62 return harness_no_relations
65 def test_mysql_missing_relation(mocker
: MockerFixture
, harness_no_relations
: Harness
):
66 spy_safe_restart
= mocker
.spy(harness_no_relations
.charm
, "_safe_restart")
67 harness_no_relations
.charm
.on
.keystone_pebble_ready
.emit("keystone")
68 assert harness_no_relations
.charm
.unit
.status
== BlockedStatus("mysql relation is missing")
69 assert spy_safe_restart
.call_count
== 1
70 harness_no_relations
.charm
.on
.config_changed
.emit()
71 assert harness_no_relations
.charm
.unit
.status
== BlockedStatus("mysql relation is missing")
72 assert spy_safe_restart
.call_count
== 2
75 def test_mysql_relation_ready(mocker
: MockerFixture
, harness
: Harness
):
76 spy
= mocker
.spy(harness
.charm
, "_safe_restart")
77 harness
.charm
.on
.config_changed
.emit()
78 assert harness
.charm
.unit
.status
== ActiveStatus()
79 assert spy
.call_count
== 1
82 def test_db_sync_action(mocker
: MockerFixture
, harness
: Harness
):
83 event_mock
= mocker
.Mock()
84 harness
.charm
._on
_db
_sync
_action
(event_mock
)
85 event_mock
.set_results
.assert_called_once_with(
86 {"output": "db-sync was successfully executed."}
88 event_mock
.fail
.assert_not_called()
89 harness
.charm
.container
.exec().wait
.side_effect
= pebble
.ExecError(
90 ["keystone-manage", "db_sync"], 1, "", "Error"
92 harness
.charm
._on
_db
_sync
_action
(event_mock
)
93 event_mock
.fail
.assert_called_once_with("db-sync action failed with code 1 and stderr Error.")
96 def test_provide_keystone_relation(mocker
: MockerFixture
, harness
: Harness
):
98 mon_rel_id
= harness
.add_relation("keystone", "mon")
99 harness
.add_relation_unit(mon_rel_id
, "mon/0")
100 data
= harness
.get_relation_data(mon_rel_id
, harness
.charm
.app
)
103 harness
.set_leader(True)
104 nbi_rel_id
= harness
.add_relation("keystone", "nbi")
105 harness
.add_relation_unit(nbi_rel_id
, "nbi/0")
106 data
= harness
.get_relation_data(nbi_rel_id
, harness
.charm
.app
)
108 "host": "http://osm-keystone:5000/v3",
110 "user_domain_name": "default",
111 "project_domain_name": "default",
114 "service": "service",
115 "keystone_db_password": "admin",
116 "region_id": "RegionOne",
117 "admin_username": "admin",
118 "admin_password": "admin",
119 "admin_project_name": "admin",
123 def test_update_status_rotation(mocker
: MockerFixture
, harness
: Harness
):
124 spy_fernet_rotate
= mocker
.spy(harness
.charm
, "_fernet_rotate")
125 harness
.set_leader(True)
126 harness
._update
_config
({"token-expiration": -1})
127 harness
.charm
.on
.update_status
.emit()
128 assert spy_fernet_rotate
.call_count
== 1
131 def test_update_status_no_rotation(mocker
: MockerFixture
, harness
: Harness
):
132 spy_fernet_rotate
= mocker
.spy(harness
.charm
, "_fernet_rotate")
133 harness
.set_leader(True)
134 harness
._update
_config
({"token-expiration": 3600})
135 harness
.charm
.on
.update_status
.emit()
136 assert spy_fernet_rotate
.call_count
== 0