• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

LudovicRousseau / PyKCS11 / 23319762925

19 Mar 2026 09:33PM UTC coverage: 94.174% (+0.6%) from 93.527%
23319762925

push

github

LudovicRousseau
GA Linux: ignore test_derive

6337 of 6729 relevant lines covered (94.17%)

0.94 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.91
/test/test_load.py
1
# pylint: disable=missing-module-docstring
2
# pylint: disable=missing-class-docstring
3
# pylint: disable=missing-function-docstring
4

5
import gc
1✔
6
import os
1✔
7
import platform
1✔
8
import shutil
1✔
9
import unittest
1✔
10
from pathlib import Path
1✔
11
from tempfile import TemporaryDirectory
1✔
12

13
from PyKCS11 import PyKCS11
1✔
14

15

16
class TestUtil(unittest.TestCase):
1✔
17
    def setUp(self):
1✔
18
        self.pkcs11 = PyKCS11.PyKCS11Lib()
1✔
19
        self.tmpdir = TemporaryDirectory()
1✔
20
        self.lib1_name = os.environ["PYKCS11LIB"]
1✔
21
        # create a tmp copy of the main lib
22
        # to use as a different library in tests
23
        self.lib2_name = str(Path(self.tmpdir.name) / Path(self.lib1_name).name)
1✔
24
        shutil.copy(self.lib1_name, self.tmpdir.name)
1✔
25

26
    def tearDown(self):
1✔
27
        del self.pkcs11
1✔
28
        if platform.system() != "Windows":
1✔
29
            self.tmpdir.cleanup()
1✔
30
        del self.tmpdir
1✔
31
        del self.lib1_name
1✔
32
        del self.lib2_name
1✔
33

34
    def openSession(self, lib):
1✔
35
        slot = lib.getSlotList(tokenPresent=True)[0]
1✔
36
        return lib.openSession(slot, PyKCS11.CKF_SERIAL_SESSION)
1✔
37

38
    def test_load(self):
1✔
39
        # create two instances with default library
40
        lib1 = PyKCS11.PyKCS11Lib().load()
1✔
41
        lib2 = PyKCS11.PyKCS11Lib().load()
1✔
42

43
        # expect two instances with the same library loaded
44
        self.assertTrue(hasattr(lib1, "pkcs11dll_filename"))
1✔
45
        self.assertTrue(hasattr(lib2, "pkcs11dll_filename"))
1✔
46
        self.assertEqual(len(lib1._loaded_libs), 1)
1✔
47
        self.assertEqual(len(lib2._loaded_libs), 1)
1✔
48

49
        self.openSession(lib1)
1✔
50

51
        # unload the first library
52
        del lib1
1✔
53
        gc.collect()
1✔
54

55
        # one instance remaining, the library is still in use
56
        self.openSession(lib2)
1✔
57
        self.assertEqual(len(lib2._loaded_libs), 1)
1✔
58

59
        # unload the second library
60
        del lib2
1✔
61
        gc.collect()
1✔
62

63
        self.assertEqual(len(self.pkcs11._loaded_libs), 0)
1✔
64

65
    def test_multiple_load(self):
1✔
66
        # load two different libraries
67
        lib1 = PyKCS11.PyKCS11Lib().load(self.lib1_name)
1✔
68
        lib2 = PyKCS11.PyKCS11Lib().load(self.lib2_name)
1✔
69

70
        # _loaded_libs is shared across all instances
71
        # check the value in self.pkcs11
72
        self.assertEqual(len(self.pkcs11._loaded_libs), 2)
1✔
73
        lib1 = PyKCS11.PyKCS11Lib()  # unload lib1
1✔
74
        self.assertEqual(len(self.pkcs11._loaded_libs), 1)
1✔
75
        lib2 = PyKCS11.PyKCS11Lib()  # unload lib2
1✔
76
        self.assertEqual(len(self.pkcs11._loaded_libs), 0)
1✔
77

78
    def test_invalid_load(self):
1✔
79
        # Library not found
80
        lib = "nolib"
1✔
81
        with self.assertRaises(PyKCS11.PyKCS11Error) as cm:
1✔
82
            self.pkcs11.load(lib)
1✔
83
        the_exception = cm.exception
1✔
84
        self.assertEqual(the_exception.value, -1)
1✔
85
        self.assertEqual(the_exception.text, lib)
1✔
86
        self.assertEqual(str(the_exception), f"Load ({lib})")
1✔
87
        self.assertEqual(len(self.pkcs11._loaded_libs), 0)
1✔
88

89
        # C_GetFunctionList() not found
90
        if platform.system() == "Linux":
1✔
91
            # GNU/Linux
92
            lib = "libc.so.6"
1✔
93
        elif platform.system() == "Darwin":
×
94
            # macOS
95
            lib = "/usr/lib/libSystem.B.dylib"
×
96
        else:
97
            # Windows
98
            lib = "WinSCard.dll"
×
99

100
        with self.assertRaises(PyKCS11.PyKCS11Error) as cm:
1✔
101
            self.pkcs11.load(lib)
1✔
102
        the_exception = cm.exception
1✔
103
        self.assertEqual(the_exception.value, -4)
1✔
104
        self.assertEqual(the_exception.text, lib)
1✔
105
        self.assertEqual(str(the_exception), f"C_GetFunctionList() not found ({lib})")
1✔
106
        self.assertEqual(len(self.pkcs11._loaded_libs), 0)
1✔
107

108
        # try to load the improper lib another time
109
        with self.assertRaises(PyKCS11.PyKCS11Error) as cm:
1✔
110
            self.pkcs11.load(lib)
1✔
111
        the_exception = cm.exception
1✔
112
        self.assertEqual(the_exception.value, -4)
1✔
113
        self.assertEqual(the_exception.text, lib)
1✔
114
        self.assertEqual(str(the_exception), f"C_GetFunctionList() not found ({lib})")
1✔
115
        self.assertEqual(len(self.pkcs11._loaded_libs), 0)
1✔
116

117
        # finally, load a valid library
118
        self.pkcs11.load()
1✔
119
        self.assertEqual(len(self.pkcs11._loaded_libs), 1)
1✔
120

121
    def test_specific_load(self):
1✔
122
        # load two different libraries sequentially
123
        self.pkcs11.load(self.lib1_name)
1✔
124
        self.pkcs11.load(self.lib2_name)
1✔
125

126
        # the second load should've unloaded the first library
127
        self.assertEqual(len(self.pkcs11._loaded_libs), 1)
1✔
128
        self.assertEqual(self.pkcs11.pkcs11dll_filename, self.lib2_name)
1✔
129

130
        # reload the first library
131
        self.pkcs11 = PyKCS11.PyKCS11Lib()
1✔
132
        self.pkcs11.load(self.lib1_name)
1✔
133

134
        # try to open a session
135
        self.assertIsNotNone(self.openSession(self.pkcs11))
1✔
136

137
    def test_unload(self):
1✔
138
        self.pkcs11.load().unload()
1✔
139
        # no pkcs11dll_filename should remain after unload
140
        self.assertIsNone(self.pkcs11.pkcs11dll_filename)
1✔
141

142
        self.pkcs11.load()
1✔
143
        self.openSession(self.pkcs11)
1✔
144
        # one library has been loaded
145
        self.assertEqual(len(self.pkcs11._loaded_libs), 1)
1✔
146
        self.assertIsNotNone(self.pkcs11.pkcs11dll_filename)
1✔
147

148
        self.pkcs11.unload()
1✔
149
        gc.collect()
1✔
150
        # manually unloaded the library using gc.collect()
151
        self.assertEqual(len(self.pkcs11._loaded_libs), 0)
1✔
152
        self.assertIsNone(self.pkcs11.pkcs11dll_filename)
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc