Skip to content

Commit

Permalink
Adding support for multithread debugging to plugin.
Browse files Browse the repository at this point in the history
  • Loading branch information
jsargiot committed Apr 14, 2013
1 parent 20b7371 commit 42b0f5d
Show file tree
Hide file tree
Showing 16 changed files with 606 additions and 0 deletions.
Empty file.
95 changes: 95 additions & 0 deletions debugger_plugin/core/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
""" """
import os

class WatchModel:
"""
"""

def __init__(self, ename, etype, evalue):
"""
"""
self.expression = ename
self.type = etype
self.value = evalue
self.children = []

def __str__(self):
"""
"""
return "{} = ({}){}".format(self.expression, self.type, self.value)

def __repr__(self):
return "WatchModel({}, {}, {})".format(repr(self.expression), repr(self.type), repr(self.value))

class ThreadGroup:
"""
"""

def __init__(self, name):
"""
"""
self.name = name
self._threads = {}

def add(self, tid, tobject):
"""
"""
self._threads[tid] = tobject

def remove(self, tid):
"""
"""
del self._threads[tid]

def get(self, tid):
return self._threads.get(tid)

def __iter__(self):
for i in self._threads:
yield self._threads[i]

def __str__(self):
return self.name

def __repr__(self):
return "ThreadGroup({})".format(repr(self.name))


class ThreadModel:
"""
"""
RUNNING = 10
PAUSED = 20
STOPPED = 30

def __init__(self, tid, tname, tstatus = STOPPED):
self.ident = tid
self.name = tname
self.state = tstatus
self.epointer = None

def __str__(self):
state = "running"
if self.state == self.PAUSED:
state = str(self.epointer)
elif self.state == self.STOPPED:
state = "stopped"
return "[{}] {} ({})".format(self.ident, self.name, state)

def __repr__(self):
return "ThreadModel({}, {}, {})".format(repr(self.ident), repr(self.name), repr(self.state))

class ThreadStackEntry:
""" """

def __init__(self, filename, linenumber):
self.filename = filename
self.linenumber = linenumber

def __str__(self):
return "{0}:{1}".format(os.path.basename(self.filename), self.linenumber)

def __repr__(self):
return "ThreadStackEntry({}, {})".format(repr(self.filename), repr(self.linenumber))
92 changes: 92 additions & 0 deletions debugger_plugin/core/test/test_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
""" """
import debugger_plugin.core.models
import unittest


class TestWatchModel(unittest.TestCase):

def test_str(self):
e_name = "a"
e_type = "int"
e_val = "1"
wmodel = debugger_plugin.core.models.WatchModel(e_name, e_type, e_val)

res = str(wmodel)

self.assertTrue(res.find(e_name) != -1)
self.assertTrue(res.find(e_type) != -1)
self.assertTrue(res.find(e_val) != -1)


class TestThreadGroup(unittest.TestCase):

#def test_get(self) also
def test_add(self):
tgroup = debugger_plugin.core.models.ThreadGroup('name')
tobj = debugger_plugin.core.models.ThreadModel(1, 'thread')
tgroup.add(1, tobj)
tobj2 = tgroup.get(1)
self.assertEquals(tobj, tobj2)

def test_add_replace(self):
tgroup = debugger_plugin.core.models.ThreadGroup('name')
tobj = debugger_plugin.core.models.ThreadModel(1, 'thread')
tobj2 = debugger_plugin.core.models.ThreadModel(1, 'thread2')
tgroup.add(1, tobj)
tgroup.add(1, tobj2)
tobj3 = tgroup.get(1)
self.assertEquals(tobj2, tobj3)

def test_remove_existing(self):
tgroup = debugger_plugin.core.models.ThreadGroup('name')
tobj = debugger_plugin.core.models.ThreadModel(1, 'thread')
tgroup.add(1, tobj)
tgroup.remove(1)
self.assertRaises(KeyError, tgroup.get, 1)

def test_remove_notexisting(self):
tgroup = debugger_plugin.core.models.ThreadGroup('name')
self.assertRaises(KeyError, tgroup.remove, 1)

def test_iter(self):
tgroup = debugger_plugin.core.models.ThreadGroup('name')
tobj1 = debugger_plugin.core.models.ThreadModel(1, 'thread')
tobj2 = debugger_plugin.core.models.ThreadModel(2, 'thread')
tgroup.add(1, tobj1)
tgroup.add(2, tobj2)
input_list = [tobj1, tobj2]
res_list = list(tgroup)
self.assertEquals(input_list, res_list)


class TestThreadModel(unittest.TestCase):
"""
"""
RUNNING = 10
PAUSED = 20
STOPPED = 30

def test_str(self):
tid = "123"
tname = "nombre"
tmodel = debugger_plugin.core.models.ThreadModel(tid, tname)
res = str(tmodel)
self.assertTrue(res.find(tid) != -1)
self.assertTrue(res.find(tname) != -1)


class TestThreadStackEntry(unittest.TestCase):
""" """

def test_str(self):
child = debugger_plugin.core.models.ThreadStackEntry("c.py", 2)
parent = debugger_plugin.core.models.ThreadStackEntry("p.py", 1, child)
res = str(parent)
self.assertTrue(res.find("p.py") != -1)
self.assertTrue(res.find("1") != -1)
self.assertEquals(parent.child, child)

if __name__ == '__main__':
unittest.main()
64 changes: 64 additions & 0 deletions debugger_plugin/gui/BaseProviders.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
This module offers a set of providers to work with basic views.
"""

class TreeContentProvider:
"""
A TreeContentProvider provides elements to the TreeViewer from the
TreeViewer's model. The TreeContentProvider adapts the model to the
ui control.
This is an "abstract interface", all methods in this class raise an
NotImplementedError.
"""

def __init__(self):
"""Creates a new TreeContentProvider."""
raise NotImplementedError('Abstract interface.')

def getChildren(self, parent):
"""Returns the child elements of the given element."""
raise NotImplementedError('Abstract interface.')

def getParent(self, element):
"""
Returns the parent of the given element. Returns None if the element
has no parent element.
"""
raise NotImplementedError('Abstract interface.')

def hasChildren(self, element):
"""Returns whether the given element has children."""
raise NotImplementedError('Abstract interface.')


class LabelProvider:
"""
A LabelProvider object maps a given element of the viewer's model to
a label (text with optional image) that is used to display the element in
the UI control.
This is a base implementation, this LabelProvider will return the string
representation for the text and no image.
"""

def __init__(self):
"""Creates a new LabelProvider."""
pass

def getText(self, obj):
"""
Returns the image for the given element. Default implementation
returns the string representation of the object.
"""
return str(obj)

def getImage(self, obj):
"""
Returns the image for the given element. Default implementation
returns no image.
"""
return None

Loading

0 comments on commit 42b0f5d

Please sign in to comment.