--- /dev/null
+#
+# Test the "files" module
+#
+
+PYTHONPATH := $(top_builddir)/src/tests/modules/python/
+export PYTHONPATH
+
+# MODULE.test is the main target for this module.
+python.test:
\ No newline at end of file
--- /dev/null
+#
+# Input packet
+#
+User-Name = "bob"
+User-Password = "hello"
+
+#
+# Expected answer
+#
+Response-Packet-Type == Access-Accept
\ No newline at end of file
--- /dev/null
+# This module is cext_compat and should work
+pmod4_cextcompat
+if (!noop) {
+ test_fail
+} else {
+ test_pass
+}
+
+# This module share the main interpreter with pmod4_cextcompat. shared_attribute should be defined
+pmod5_cextcompat
+if (!ok) {
+ test_fail
+} else {
+ test_pass
+}
+
+# This module has it's own SubInterpreter. shared_attribute shouldn't be defined
+pmod4_not_cextcompat
+if (!noop) {
+ test_fail
+} else {
+ test_pass
+}
+
+# This module has it's own SubInterpreter. shared_attribute shouldn't be defined
+pmod5_not_cextcompat
+if (!noop) {
+ test_fail
+} else {
+ test_pass
+}
\ No newline at end of file
--- /dev/null
+#
+# Input packet
+#
+User-Name = "bob"
+User-Password = "hello"
+
+#
+# Expected answer
+#
+Response-Packet-Type == Access-Accept
\ No newline at end of file
--- /dev/null
+pmod6_configured
+if (!ok) {
+ test_fail
+} else {
+ test_pass
+}
\ No newline at end of file
--- /dev/null
+#
+# Input packet
+#
+User-Name = "bob"
+User-Password = "hello"
+
+#
+# Expected answer
+#
+Response-Packet-Type == Access-Accept
\ No newline at end of file
--- /dev/null
+# Call the second configured module firstly should work
+pmod2
+if (!ok) {
+ test_fail
+} else {
+ test_pass
+}
+
+# Call the first configured module secondly
+pmod1
+if (!noop) {
+ test_fail
+} else {
+ test_pass
+}
\ No newline at end of file
--- /dev/null
+#
+# Input packet
+#
+User-Name = "bob"
+User-Password = "hello"
+
+#
+# Expected answer
+#
+Response-Packet-Type == Access-Accept
\ No newline at end of file
--- /dev/null
+# The first call on pmod1 should store var "tls" in a thread local storage and return noop
+pmod1
+if (!noop) {
+ test_fail
+} else {
+ test_pass
+}
+
+# Simply call another second module
+pmod2
+if (!ok) {
+ test_fail
+} else {
+ test_pass
+}
+
+# The second call on pmod1 should return OK because "tls" is set
+pmod1
+if (!ok) {
+ test_fail
+} else {
+ test_pass
+}
+
+# Calling another python module configured with mod1.py should be in it's own context and return NOOP on first call
+pmod3_withmod1
+if (!noop) {
+ test_fail
+} else {
+ test_pass
+}
+
+# Should return "OK" on subsequent calls
+pmod3_withmod1
+if (!ok) {
+ test_fail
+} else {
+ test_pass
+}
+
+pmod3_withmod1
+if (!ok) {
+ test_fail
+} else {
+ test_pass
+}
\ No newline at end of file
--- /dev/null
+import radiusd
+import threading
+
+local = threading.local()
+
+def authorize(p):
+ global local
+ if hasattr(local, 'tls'):
+ return radiusd.RLM_MODULE_OK
+ else:
+ local.tls = True
+ return radiusd.RLM_MODULE_NOOP
\ No newline at end of file
--- /dev/null
+import radiusd
+
+def authorize(p):
+ return radiusd.RLM_MODULE_OK
\ No newline at end of file
--- /dev/null
+import radiusd
+import shared
+
+def authorize(p):
+ if not hasattr(shared, 'shared_attribute'):
+ setattr(shared, 'shared_attribute', True)
+ return radiusd.RLM_MODULE_NOOP
+
+ return radiusd.RLM_MODULE_OK
+
--- /dev/null
+import radiusd
+
+def authorize(p):
+ if radiusd.config.get('a_param'):
+ return radiusd.RLM_MODULE_OK
+
+ return radiusd.RLM_MODULE_NOOP
\ No newline at end of file
--- /dev/null
+python pmod1 {
+ module = 'mod1'
+
+ mod_authorize = ${.module}
+ func_authorize = authorize
+
+ cext_compat = false
+}
+
+python pmod2 {
+ module = 'mod2'
+
+ mod_authorize = ${.module}
+ func_authorize = authorize
+
+ cext_compat = false
+}
+
+python pmod3_withmod1 {
+ module = 'mod1'
+
+ mod_authorize = ${.module}
+ func_authorize = authorize
+
+ cext_compat = false
+}
+
+python pmod4_cextcompat {
+ module = 'mod3'
+
+ mod_authorize = ${.module}
+ func_authorize = authorize
+
+ cext_compat = true
+}
+
+python pmod5_cextcompat {
+ module = 'mod3'
+
+ mod_authorize = ${.module}
+ func_authorize = authorize
+
+ cext_compat = true
+}
+
+python pmod4_not_cextcompat {
+ module = 'mod3'
+
+ mod_authorize = ${.module}
+ func_authorize = authorize
+
+ cext_compat = false
+}
+
+python pmod5_not_cextcompat {
+ module = 'mod3'
+
+ mod_authorize = ${.module}
+ func_authorize = authorize
+
+ cext_compat = false
+}
+
+python pmod6_configured {
+ module = 'mod4'
+
+ mod_authorize = ${.module}
+ func_authorize = authorize
+
+ config {
+ a_param = "a_value"
+ }
+
+ cext_compat = false
+}
\ No newline at end of file
--- /dev/null
+dummy_attribute = 0
\ No newline at end of file