Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

"""Tests for certbot.plugins.disco.""" 

import functools 

import string 

import unittest 

 

import mock 

import pkg_resources 

import six 

import zope.interface 

 

from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module 

from certbot import errors 

from certbot import interfaces 

 

from certbot.plugins import standalone 

from certbot.plugins import webroot 

 

EP_SA = pkg_resources.EntryPoint( 

"sa", "certbot.plugins.standalone", 

attrs=("Authenticator",), 

dist=mock.MagicMock(key="certbot")) 

EP_WR = pkg_resources.EntryPoint( 

"wr", "certbot.plugins.webroot", 

attrs=("Authenticator",), 

dist=mock.MagicMock(key="certbot")) 

 

 

class PluginEntryPointTest(unittest.TestCase): 

"""Tests for certbot.plugins.disco.PluginEntryPoint.""" 

 

def setUp(self): 

self.ep1 = pkg_resources.EntryPoint( 

"ep1", "p1.ep1", dist=mock.MagicMock(key="p1")) 

self.ep1prim = pkg_resources.EntryPoint( 

"ep1", "p2.ep2", dist=mock.MagicMock(key="p2")) 

# nested 

self.ep2 = pkg_resources.EntryPoint( 

"ep2", "p2.foo.ep2", dist=mock.MagicMock(key="p2")) 

# project name != top-level package name 

self.ep3 = pkg_resources.EntryPoint( 

"ep3", "a.ep3", dist=mock.MagicMock(key="p3")) 

 

from certbot.plugins.disco import PluginEntryPoint 

self.plugin_ep = PluginEntryPoint(EP_SA) 

 

def test_entry_point_to_plugin_name(self): 

from certbot.plugins.disco import PluginEntryPoint 

 

names = { 

self.ep1: "p1:ep1", 

self.ep1prim: "p2:ep1", 

self.ep2: "p2:ep2", 

self.ep3: "p3:ep3", 

EP_SA: "sa", 

} 

 

for entry_point, name in six.iteritems(names): 

self.assertEqual( 

name, PluginEntryPoint.entry_point_to_plugin_name(entry_point)) 

 

def test_description(self): 

self.assertTrue("temporary webserver" in self.plugin_ep.description) 

 

def test_description_with_name(self): 

self.plugin_ep.plugin_cls = mock.MagicMock(description="Desc") 

self.assertEqual( 

"Desc (sa)", self.plugin_ep.description_with_name) 

 

def test_long_description(self): 

self.plugin_ep.plugin_cls = mock.MagicMock( 

long_description="Long desc") 

self.assertEqual( 

"Long desc", self.plugin_ep.long_description) 

 

def test_long_description_nonexistent(self): 

self.plugin_ep.plugin_cls = mock.MagicMock( 

description="Long desc not found", spec=["description"]) 

self.assertEqual( 

"Long desc not found", self.plugin_ep.long_description) 

 

def test_ifaces(self): 

self.assertTrue(self.plugin_ep.ifaces((interfaces.IAuthenticator,))) 

self.assertFalse(self.plugin_ep.ifaces((interfaces.IInstaller,))) 

self.assertFalse(self.plugin_ep.ifaces(( 

interfaces.IInstaller, interfaces.IAuthenticator))) 

 

def test__init__(self): 

self.assertFalse(self.plugin_ep.initialized) 

self.assertFalse(self.plugin_ep.prepared) 

self.assertFalse(self.plugin_ep.misconfigured) 

self.assertFalse(self.plugin_ep.available) 

self.assertTrue(self.plugin_ep.problem is None) 

self.assertTrue(self.plugin_ep.entry_point is EP_SA) 

self.assertEqual("sa", self.plugin_ep.name) 

 

self.assertTrue(self.plugin_ep.plugin_cls is standalone.Authenticator) 

 

def test_init(self): 

config = mock.MagicMock() 

plugin = self.plugin_ep.init(config=config) 

self.assertTrue(self.plugin_ep.initialized) 

self.assertTrue(plugin.config is config) 

# memoize! 

self.assertTrue(self.plugin_ep.init() is plugin) 

self.assertTrue(plugin.config is config) 

# try to give different config 

self.assertTrue(self.plugin_ep.init(123) is plugin) 

self.assertTrue(plugin.config is config) 

 

self.assertFalse(self.plugin_ep.prepared) 

self.assertFalse(self.plugin_ep.misconfigured) 

self.assertFalse(self.plugin_ep.available) 

 

def test_verify(self): 

iface1 = mock.MagicMock(__name__="iface1") 

iface2 = mock.MagicMock(__name__="iface2") 

iface3 = mock.MagicMock(__name__="iface3") 

# pylint: disable=protected-access 

self.plugin_ep._initialized = plugin = mock.MagicMock() 

 

exceptions = zope.interface.exceptions 

with mock.patch("certbot.plugins." 

"disco.zope.interface") as mock_zope: 

mock_zope.exceptions = exceptions 

 

def verify_object(iface, obj): # pylint: disable=missing-docstring 

assert obj is plugin 

assert iface is iface1 or iface is iface2 or iface is iface3 

if iface is iface3: 

raise mock_zope.exceptions.BrokenImplementation(None, None) 

mock_zope.verify.verifyObject.side_effect = verify_object 

self.assertTrue(self.plugin_ep.verify((iface1,))) 

self.assertTrue(self.plugin_ep.verify((iface1, iface2))) 

self.assertFalse(self.plugin_ep.verify((iface3,))) 

self.assertFalse(self.plugin_ep.verify((iface1, iface3))) 

 

def test_prepare(self): 

config = mock.MagicMock() 

self.plugin_ep.init(config=config) 

self.plugin_ep.prepare() 

self.assertTrue(self.plugin_ep.prepared) 

self.assertFalse(self.plugin_ep.misconfigured) 

 

# output doesn't matter that much, just test if it runs 

str(self.plugin_ep) 

 

def test_prepare_misconfigured(self): 

plugin = mock.MagicMock() 

plugin.prepare.side_effect = errors.MisconfigurationError 

# pylint: disable=protected-access 

self.plugin_ep._initialized = plugin 

self.assertTrue(isinstance(self.plugin_ep.prepare(), 

errors.MisconfigurationError)) 

self.assertTrue(self.plugin_ep.prepared) 

self.assertTrue(self.plugin_ep.misconfigured) 

self.assertTrue(isinstance(self.plugin_ep.problem, 

errors.MisconfigurationError)) 

self.assertTrue(self.plugin_ep.available) 

 

def test_prepare_no_installation(self): 

plugin = mock.MagicMock() 

plugin.prepare.side_effect = errors.NoInstallationError 

# pylint: disable=protected-access 

self.plugin_ep._initialized = plugin 

self.assertTrue(isinstance(self.plugin_ep.prepare(), 

errors.NoInstallationError)) 

self.assertTrue(self.plugin_ep.prepared) 

self.assertFalse(self.plugin_ep.misconfigured) 

self.assertFalse(self.plugin_ep.available) 

 

def test_prepare_generic_plugin_error(self): 

plugin = mock.MagicMock() 

plugin.prepare.side_effect = errors.PluginError 

# pylint: disable=protected-access 

self.plugin_ep._initialized = plugin 

self.assertTrue(isinstance(self.plugin_ep.prepare(), errors.PluginError)) 

self.assertTrue(self.plugin_ep.prepared) 

self.assertFalse(self.plugin_ep.misconfigured) 

self.assertFalse(self.plugin_ep.available) 

 

def test_repr(self): 

self.assertEqual("PluginEntryPoint#sa", repr(self.plugin_ep)) 

 

 

class PluginsRegistryTest(unittest.TestCase): 

"""Tests for certbot.plugins.disco.PluginsRegistry.""" 

 

@classmethod 

def _create_new_registry(cls, plugins): 

from certbot.plugins.disco import PluginsRegistry 

return PluginsRegistry(plugins) 

 

def setUp(self): 

self.plugin_ep = mock.MagicMock() 

self.plugin_ep.name = "mock" 

self.plugin_ep.__hash__.side_effect = TypeError 

self.plugins = {self.plugin_ep.name: self.plugin_ep} 

self.reg = self._create_new_registry(self.plugins) 

 

def test_find_all(self): 

from certbot.plugins.disco import PluginsRegistry 

with mock.patch("certbot.plugins.disco.pkg_resources") as mock_pkg: 

mock_pkg.iter_entry_points.side_effect = [iter([EP_SA]), 

iter([EP_WR])] 

plugins = PluginsRegistry.find_all() 

self.assertTrue(plugins["sa"].plugin_cls is standalone.Authenticator) 

self.assertTrue(plugins["sa"].entry_point is EP_SA) 

self.assertTrue(plugins["wr"].plugin_cls is webroot.Authenticator) 

self.assertTrue(plugins["wr"].entry_point is EP_WR) 

 

def test_getitem(self): 

self.assertEqual(self.plugin_ep, self.reg["mock"]) 

 

def test_iter(self): 

self.assertEqual(["mock"], list(self.reg)) 

 

def test_len(self): 

self.assertEqual(0, len(self._create_new_registry({}))) 

self.assertEqual(1, len(self.reg)) 

 

def test_init(self): 

self.plugin_ep.init.return_value = "baz" 

self.assertEqual(["baz"], self.reg.init("bar")) 

self.plugin_ep.init.assert_called_once_with("bar") 

 

def test_filter(self): 

self.assertEqual( 

self.plugins, 

self.reg.filter(lambda p_ep: p_ep.name.startswith("m"))) 

self.assertEqual( 

{}, self.reg.filter(lambda p_ep: p_ep.name.startswith("b"))) 

 

def test_ifaces(self): 

self.plugin_ep.ifaces.return_value = True 

# pylint: disable=protected-access 

self.assertEqual(self.plugins, self.reg.ifaces()._plugins) 

self.plugin_ep.ifaces.return_value = False 

self.assertEqual({}, self.reg.ifaces()._plugins) 

 

def test_verify(self): 

self.plugin_ep.verify.return_value = True 

# pylint: disable=protected-access 

self.assertEqual( 

self.plugins, self.reg.verify(mock.MagicMock())._plugins) 

self.plugin_ep.verify.return_value = False 

self.assertEqual({}, self.reg.verify(mock.MagicMock())._plugins) 

 

def test_prepare(self): 

self.plugin_ep.prepare.return_value = "baz" 

self.assertEqual(["baz"], self.reg.prepare()) 

self.plugin_ep.prepare.assert_called_once_with() 

 

def test_prepare_order(self): 

order = [] # type: List[str] 

plugins = dict( 

(c, mock.MagicMock(prepare=functools.partial(order.append, c))) 

for c in string.ascii_letters) 

reg = self._create_new_registry(plugins) 

reg.prepare() 

# order of prepare calls must be sorted to prevent deadlock 

# caused by plugins acquiring locks during prepare 

self.assertEqual(order, sorted(string.ascii_letters)) 

 

def test_available(self): 

self.plugin_ep.available = True 

# pylint: disable=protected-access 

self.assertEqual(self.plugins, self.reg.available()._plugins) 

self.plugin_ep.available = False 

self.assertEqual({}, self.reg.available()._plugins) 

 

def test_find_init(self): 

self.assertTrue(self.reg.find_init(mock.Mock()) is None) 

self.plugin_ep.initialized = True 

self.assertTrue( 

self.reg.find_init(self.plugin_ep.init()) is self.plugin_ep) 

 

def test_repr(self): 

self.plugin_ep.__repr__ = lambda _: "PluginEntryPoint#mock" 

self.assertEqual("PluginsRegistry(PluginEntryPoint#mock)", 

repr(self.reg)) 

 

def test_str(self): 

self.assertEqual("No plugins", str(self._create_new_registry({}))) 

self.plugin_ep.__str__ = lambda _: "Mock" 

self.assertEqual("Mock", str(self.reg)) 

plugins = {self.plugin_ep.name: self.plugin_ep, "foo": "Bar"} 

reg = self._create_new_registry(plugins) 

self.assertEqual("Bar\n\nMock", str(reg)) 

 

 

if __name__ == "__main__": 

unittest.main() # pragma: no cover