5 // Gabriel Burt <gburt@novell.com>
7 // Copyright (C) 2009 Novell, Inc.
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System
.Threading
;
31 using NUnit
.Framework
;
35 using Hyena
.Data
.Sqlite
;
37 using Hyena
.CommandLine
;
40 using Banshee
.Collection
;
41 using Banshee
.Collection
.Database
;
43 using Banshee
.ServiceStack
;
45 namespace Banshee
.Tests
48 public class PerformanceTests
51 private string select_single_command
;
55 private void ReloadMusicLibrary (string filter
)
57 ReloadMusicLibrary (filter
, 1.0);
60 private void ReloadMusicLibrary (string filter
, double runFactor
)
62 music_library
.FilterQuery
= filter
;
63 for (int i
= 0; i
< NUM
*runFactor
; i
++) {
64 music_library
.Reload ();
69 [Category ("Performance")]
72 ReloadMusicLibrary ("", .25);
76 [Category ("Performance")]
77 public void ReloadD ()
79 ReloadMusicLibrary ("d", .25);
83 [Category ("Performance")]
84 public void ReloadDave ()
86 ReloadMusicLibrary ("dave");
90 [Category ("Performance")]
91 public void ReloadByDave ()
93 ReloadMusicLibrary ("by:dave");
97 [Category ("Performance")]
98 public void ReloadFavorites ()
100 ReloadMusicLibrary ("rating>3");
104 [Category ("Performance")]
105 public void ReloadGenreRock ()
107 ReloadMusicLibrary ("genre:rock");
115 [Category ("Performance")]
116 public void ScrollLinear ()
118 music_library
.FilterQuery
= "";
119 int count
= Math
.Min (2500, music_library
.FilteredCount
);
120 bool any_null
= false;
122 for (int i
= 0; i
< 6; i
++) {
123 for (int j
= 0; j
< count
; j
++) {
124 any_null
|= music_library
.TrackModel
[j
] == null;
126 music_library
.DatabaseTrackModel
.InvalidateCache (false);
129 Assert
.IsFalse (any_null
);
133 [Category ("Performance")]
134 public void FetchTrack ()
136 var track
= music_library
.TrackModel
[0] as DatabaseTrackInfo
;
137 int track_id
= track
.TrackId
;
138 var cmd
= new HyenaSqliteCommand (select_single_command
, track_id
);
139 var db
= ServiceManager
.DbConnection
;
141 for (int i
= 0; i
< NUM
* 30; i
++) {
142 using (IDataReader reader
= db
.Query (cmd
)) {
143 if (reader
.Read ()) {
151 public void LoadTrack ()
153 var track
= music_library
.TrackModel
[0] as DatabaseTrackInfo
;
154 var provider
= DatabaseTrackInfo
.Provider
;
155 int track_id
= track
.TrackId
;
156 var cmd
= new HyenaSqliteCommand (select_single_command
, track_id
);
157 var db
= ServiceManager
.DbConnection
;
158 IDataReader reader
= db
.Query (cmd
);
159 Assert
.IsTrue (reader
.Read ());
161 for (int i
= 0; i
< NUM
*1000; i
++) {
162 provider
.Load (reader
, track
);
168 private void Select
<T
> (T val
)
171 var cmd
= new HyenaSqliteCommand ("SELECT ?", val
);
172 Log
.DebugFormat ("Select<T> cmd is {0}", cmd
.Text
);
173 var db
= ServiceManager
.DbConnection
;
175 for (int i
= 0; i
< NUM
* 250; i
++) {
176 res
= db
.Query
<T
> (cmd
);
178 Assert
.AreEqual (val
, res
);
182 [Category ("Performance")]
183 public void SelectStrings ()
189 [Category ("Performance")]
190 public void SelectInt ()
196 [Category ("Performance")]
197 public void SelectLong ()
203 [Category ("Performance")]
204 public void SelectDateTime ()
206 Select (new DateTime (1999, 2, 3));
210 [Category ("Performance")]
211 public void SelectBool ()
220 private void SortMusicLibrary (QueryField field
)
222 SortableColumn column
= new SortableColumn (field
);
223 music_library
.FilterQuery
= "";
225 for (int i
= 0; i
< NUM
/2; i
++) {
226 music_library
.DatabaseTrackModel
.Sort (column
);
227 music_library
.Reload ();
232 [Category ("Performance")]
233 public void SortTrack ()
235 SortMusicLibrary (BansheeQuery
.TrackNumberField
);
239 [Category ("Performance")]
240 public void SortArtist ()
242 SortMusicLibrary (BansheeQuery
.ArtistField
);
246 [Category ("Performance")]
247 public void SortRating ()
249 SortMusicLibrary (BansheeQuery
.RatingField
);
253 [Category ("Performance")]
254 public void SortLastPlayed ()
256 SortMusicLibrary (BansheeQuery
.LastPlayedField
);
263 private Thread main_thread
;
264 private HeadlessClient client
;
265 private Banshee
.Library
.MusicLibrarySource music_library
;
270 ApplicationContext
.CommandLine
= new CommandLineParser (new string [] {
272 Environment
.GetEnvironmentVariable ("BANSHEE_DEV_OPTIONS") }, 0);
273 Log
.Debugging
= false;
274 Paths
.ApplicationName
= Application
.InternalName
;
276 Application
.TimeoutHandler
= RunTimeout
;
277 Application
.IdleHandler
= RunIdle
;
278 Application
.IdleTimeoutRemoveHandler
= IdleTimeoutRemove
;
279 Application
.Initialize ();
281 client
= new HeadlessClient ();
282 main_thread
= new Thread (RunBanshee
);
283 main_thread
.Start ();
284 while (!client
.IsStarted
) {}
287 private void RunBanshee ()
290 Gtk
.Application
.Init ();
291 ThreadAssist
.InitializeMainThread ();
292 ThreadAssist
.ProxyToMainHandler
= Banshee
.ServiceStack
.Application
.Invoke
;
293 Application
.PushClient (client
);
296 music_library
= ServiceManager
.SourceManager
.MusicLibrary
;
298 var provider
= DatabaseTrackInfo
.Provider
;
299 select_single_command
= String
.Format (
300 "SELECT {0} FROM {1} WHERE {2}{3}{4} = ?",
301 provider
.Select
, provider
.From
, provider
.Where
,
302 (String
.IsNullOrEmpty (provider
.Where
) ? String
.Empty
: " AND "),
307 } catch (Exception e
) {
308 Console
.WriteLine (e
);
313 [TestFixtureTearDown
]
314 [Category ("Performance")]
315 public void Teardown ()
317 ThreadAssist
.ProxyToMain (Application
.Shutdown
);
322 protected uint RunTimeout (uint milliseconds
, TimeoutHandler handler
)
324 return GLib
.Timeout
.Add (milliseconds
, delegate { return handler (); }
);
327 protected uint RunIdle (IdleHandler handler
)
329 return GLib
.Idle
.Add (delegate { return handler (); }
);
332 protected bool IdleTimeoutRemove (uint id
)
334 return GLib
.Source
.Remove (id
);
339 public static void Main (string [] args
)
341 var tests
= new PerformanceTests ();
344 using (new Hyena
.Timer ("Performance.exe Tests")) {
345 tests
.ScrollLinear ();
353 public class SortableColumn
: ISortableColumn
358 public SortableColumn (QueryField field
)
363 public string SortKey { get { return field.Name; }
}
365 public SortType SortType
{
366 get { return sort_type; }
367 set { sort_type = value; }
370 public Hyena
.Query
.QueryField Field { get { return field; }
}
372 public string Id { get { return field.Name; }
}
375 public class HeadlessClient
: Client
377 public override string ClientId
{
378 get { return "Headless"; }
381 public HeadlessClient ()