GtkSharp/sample/opaquetest/OpaqueTest.cs
Dan Winship 12cd8d0d17 * generator/OpaqueGen.cs (Generate): Tweak the generated Ref/Unref
a bit; only Ref the pointer if Owned is false (and then set it to
	true), and vice versa for Unref.

	* glib/Opaque.cs (Opaque): set owned before setting Raw, so
	that Raw will be reffed properly.
	(GetOpaque): Fix this up to dtrt in all cases with refcounted
	opaques.
	
	* gtk/TreeView.custom (GetPathAtPos): Use "GetOpaque(...)" rather
	than "new TreePath()"

	* sample/opaquetest/*: regression test for opaque free/ref/unref
	handling

	* sample/Makefile.am (SUBDIRS): add opaquetest

	* configure.in.in (AC_OUTPUT): add opaquetest files

svn path=/trunk/gtk-sharp/; revision=48168
2005-08-09 14:44:32 +00:00

282 lines
9.3 KiB
C#

// Opaquetest.cs: GLib.Opaque regression test
//
// Copyright (c) 2005 Novell, Inc.
using Gtksharp;
using System;
public class OpaqueTest {
static int errors = 0;
static void GC ()
{
System.GC.Collect ();
System.GC.WaitForPendingFinalizers ();
System.GC.Collect ();
System.GC.WaitForPendingFinalizers ();
}
public static int Main ()
{
Gtk.Application.Init ();
TestOpaque ();
Console.WriteLine ();
TestRefcounted ();
Console.WriteLine ();
Console.WriteLine ("{0} errors", errors);
return errors;
}
static Opaque ret_op;
static Opaque ReturnOpaque ()
{
return ret_op;
}
static void TestOpaque ()
{
Opaque op, op1;
IntPtr handle;
Console.WriteLine ("Testing Opaque new/free");
op = new Opaque ();
if (!op.Owned)
Error ("Newly-created Opaque is not Owned");
handle = op.Handle;
op.Dispose ();
op = new Opaque (handle);
if (op.Owned)
Error ("IntPtr-created Opaque is Owned");
if (Opaquetest.Error)
Error ("Memory error after initial new/free.");
Opaquetest.ExpectError = true;
if (op.Serial != Opaque.LastSerial)
Error ("Serial mismatch. Expected {0}, Got {1}", Opaque.LastSerial, op.Serial);
if (!Opaquetest.Error)
Error ("Opaque not properly freed.");
op.Dispose ();
if (Opaquetest.Error)
Error ("Opaque created from IntPtr was freed by gtk#");
Console.WriteLine ("Testing Opaque copy/free");
op = new Opaque ();
op1 = op.Copy ();
handle = op1.Handle;
op.Dispose ();
op1.Dispose ();
if (Opaquetest.Error)
Error ("Memory error after initial copy/free.");
op = new Opaque (handle);
Opaquetest.ExpectError = true;
if (op.Serial != Opaque.LastSerial)
Error ("Serial mismatch. Expected {0}, Got {1}", Opaque.LastSerial, op.Serial);
if (!Opaquetest.Error)
Error ("Opaque not properly freed.");
op.Dispose ();
if (Opaquetest.Error)
Error ("Opaque created from IntPtr was freed by gtk#");
Console.WriteLine ("Testing non-owned return.");
op = new Opaque ();
op1 = new Opaque ();
op.Friend = op1;
if (Opaquetest.Error)
Error ("Memory error after setting op.Friend.");
op1 = op.Friend;
if (op1.Serial != Opaque.LastSerial || Opaquetest.Error)
Error ("Error reading op.Friend. Expected {0}, Got {1}", Opaque.LastSerial, op1.Serial);
if (!op1.Owned)
Error ("op1 not Owned after being read off op.Friend");
op.Dispose ();
op1.Dispose ();
if (Opaquetest.Error)
Error ("Memory error after freeing op and op1.");
Console.WriteLine ("Testing returning a Gtk#-owned opaque from C# to C");
ret_op = new Opaque ();
op = Opaque.Check (ReturnOpaque, GC);
if (op.Serial != Opaque.LastSerial || Opaquetest.Error)
Error ("Error during Opaque.Check. Expected {0}, Got {1}", Opaque.LastSerial, op.Serial);
op.Dispose ();
if (Opaquetest.Error)
Error ("Memory error after clearing op.");
Console.WriteLine ("Testing returning a Gtk#-owned opaque to a C method that will free it");
ret_op = new Opaque ();
op = Opaque.CheckFree (ReturnOpaque, GC);
if (Opaquetest.Error)
Error ("Error during Opaque.CheckFree.");
Opaquetest.ExpectError = true;
if (op.Serial != Opaque.LastSerial)
Error ("Error during Opaque.CheckFree. Expected {0}, Got {1}", Opaque.LastSerial, op.Serial);
if (!Opaquetest.Error)
Error ("Didn't get expected error accessing op.Serial!");
Opaquetest.ExpectError = true;
op.Dispose ();
if (!Opaquetest.Error)
Error ("Didn't get expected double free on op after CheckFree!");
Console.WriteLine ("Testing leaking a C-owned opaque");
ret_op = new Opaque ();
ret_op.Owned = false;
op = Opaque.Check (ReturnOpaque, GC);
if (op.Serial != Opaque.LastSerial || Opaquetest.Error)
Error ("Error during Opaque.Check. Expected {0}, Got {1}", Opaque.LastSerial, op.Serial);
handle = op.Handle;
op.Dispose ();
if (Opaquetest.Error)
Error ("Memory error after disposing op.");
op = new Opaque (handle);
if (op.Serial != Opaque.LastSerial || Opaquetest.Error)
Error ("Failed to leak op. Expected {0}, Got {1}", Opaque.LastSerial, op.Serial);
Console.WriteLine ("Testing handing over a C-owned opaque to a C method that will free it");
ret_op = new Opaque ();
ret_op.Owned = false;
op = Opaque.CheckFree (ReturnOpaque, GC);
if (Opaquetest.Error)
Error ("Error during Opaque.CheckFree.");
Opaquetest.ExpectError = true;
if (op.Serial != Opaque.LastSerial)
Error ("Error during Opaque.CheckFree. Expected {0}, Got {1}", Opaque.LastSerial, op.Serial);
if (!Opaquetest.Error)
Error ("Didn't get expected error accessing op.Serial!");
op.Dispose ();
if (Opaquetest.Error)
Error ("Double free on op!");
}
static Refcounted ret_ref;
static Refcounted ReturnRefcounted ()
{
return ret_ref;
}
static void TestRefcounted ()
{
Refcounted ref1, ref2;
IntPtr handle;
Console.WriteLine ("Testing Refcounted new/free");
ref1 = new Refcounted ();
if (!ref1.Owned)
Error ("Newly-created Refcounted is not Owned");
handle = ref1.Handle;
ref1.Dispose ();
Opaquetest.ExpectError = true;
ref1 = new Refcounted (handle);
if (!Opaquetest.Error)
Error ("Didn't get expected ref error resurrecting ref1.");
if (!ref1.Owned)
Error ("IntPtr-created Refcounted is not Owned");
Opaquetest.ExpectError = true;
if (ref1.Serial != Refcounted.LastSerial)
Error ("Serial mismatch. Expected {0}, Got {1}", Refcounted.LastSerial, ref1.Serial);
// We caused it to take a ref on the "freed" underlying object, so
// undo that now so it doesn't cause an error later when we're not
// expecting it.
Opaquetest.ExpectError = true;
ref1.Dispose ();
Opaquetest.Error = false;
Console.WriteLine ("Testing Refcounted leak/non-free");
ref1 = new Refcounted ();
ref1.Owned = false;
handle = ref1.Handle;
ref1.Dispose ();
ref1 = new Refcounted (handle);
if (Opaquetest.Error)
Error ("Non-owned ref was freed by gtk#");
if (ref1.Serial != Refcounted.LastSerial)
Error ("Serial mismatch. Expected {0}, Got {1}", Refcounted.LastSerial, ref1.Serial);
if (Opaquetest.Error)
Error ("Non-owned ref was freed by gtk#");
Console.WriteLine ("Testing non-owned return.");
ref1 = new Refcounted ();
ref2 = new Refcounted ();
ref1.Friend = ref2;
if (Opaquetest.Error)
Error ("Memory error after setting ref1.Friend.");
if (ref2.Refcount != 2)
Error ("Refcount wrong for ref2 after setting ref1.Friend. Expected 2, Got {0}", ref2.Refcount);
ref2.Dispose ();
ref2 = ref1.Friend;
if (ref2.Serial != Refcounted.LastSerial || Opaquetest.Error)
Error ("Error reading ref1.Friend. Expected {0}, Got {1}", Refcounted.LastSerial, ref2.Serial);
if (ref2.Refcount != 2 || Opaquetest.Error)
Error ("Refcount wrong for ref2 after reading ref1.Friend. Expected 2, Got {0}", ref2.Refcount);
if (!ref2.Owned)
Error ("ref2 not Owned after being read off ref1.Friend");
ref1.Dispose ();
ref2.Dispose ();
if (Opaquetest.Error)
Error ("Memory error after freeing ref1 and ref2.");
Console.WriteLine ("Testing returning a Gtk#-owned refcounted from C# to C");
ret_ref = new Refcounted ();
ref1 = Refcounted.Check (ReturnRefcounted, GC);
if (ref1.Serial != Refcounted.LastSerial || Opaquetest.Error)
Error ("Error during Refcounted.Check. Expected {0}, Got {1}", Refcounted.LastSerial, ref1.Serial);
ref1.Dispose ();
if (Opaquetest.Error)
Error ("Memory error after clearing ref1.");
Console.WriteLine ("Testing returning a Gtk#-owned refcounted to a C method that will free it");
ret_ref = new Refcounted ();
ref1 = Refcounted.CheckUnref (ReturnRefcounted, GC);
if (Opaquetest.Error)
Error ("Error during Refcounted.CheckUnref.");
Opaquetest.ExpectError = true;
if (ref1.Serial != Refcounted.LastSerial)
Error ("Error during Refcounted.CheckUnref. Expected {0}, Got {1}", Refcounted.LastSerial, ref1.Serial);
if (!Opaquetest.Error)
Error ("Didn't get expected error accessing ref1.Serial!");
Opaquetest.ExpectError = true;
ref1.Dispose ();
if (!Opaquetest.Error)
Error ("Didn't get expected double free on ref1 after CheckUnref!");
Console.WriteLine ("Testing leaking a C-owned refcounted");
ret_ref = new Refcounted ();
ret_ref.Owned = false;
ref1 = Refcounted.Check (ReturnRefcounted, GC);
if (ref1.Serial != Refcounted.LastSerial || Opaquetest.Error)
Error ("Error during Refcounted.Check. Expected {0}, Got {1}", Refcounted.LastSerial, ref1.Serial);
handle = ref1.Handle;
ref1.Dispose ();
if (Opaquetest.Error)
Error ("Memory error after disposing ref1.");
ref1 = new Refcounted (handle);
if (ref1.Serial != Refcounted.LastSerial || Opaquetest.Error)
Error ("Failed to leak ref1. Expected {0}, Got {1}", Refcounted.LastSerial, ref1.Serial);
Console.WriteLine ("Testing handing over a C-owned refcounted to a C method that will free it");
ret_ref = new Refcounted ();
ret_ref.Owned = false;
ref1 = Refcounted.CheckUnref (ReturnRefcounted, GC);
if (Opaquetest.Error)
Error ("Error during Refcounted.CheckUnref.");
Opaquetest.ExpectError = true;
if (ref1.Serial != Refcounted.LastSerial)
Error ("Error during Refcounted.CheckUnref. Expected {0}, Got {1}", Refcounted.LastSerial, ref1.Serial);
if (!Opaquetest.Error)
Error ("Didn't get expected error accessing ref1.Serial!");
ref1.Dispose ();
if (Opaquetest.Error)
Error ("Double free on ref1!");
}
static void Error (string message, params object[] args)
{
Console.Error.WriteLine (" MANAGED ERROR: " + message, args);
errors++;
}
}