768bee7b48c4f4579dc9083e37fa795c1214196f
[ardour.git] / libs / ardour / test / test_util.cc
1 /*
2     Copyright (C) 2011 Paul Davis
3     Copyright (C) 2011 Tim Mayberry
4
5     This program is free software; you can redistribute it and/or modify it
6     under the terms of the GNU General Public License as published by the Free
7     Software Foundation; either version 2 of the License, or (at your option)
8     any later version.
9
10     This program is distributed in the hope that it will be useful, but WITHOUT
11     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13     for more details.
14
15     You should have received a copy of the GNU General Public License along
16     with this program; if not, write to the Free Software Foundation, Inc.,
17     675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 #include <fstream>
20 #include <sstream>
21
22 #include <glibmm/fileutils.h>
23 #include <glibmm/miscutils.h>
24
25 #include "pbd/xml++.h"
26 #include "pbd/textreceiver.h"
27
28 #include "ardour/session.h"
29 #include "ardour/audioengine.h"
30
31 #include "test_util.h"
32
33 #include <cppunit/extensions/HelperMacros.h>
34
35 using namespace std;
36 using namespace ARDOUR;
37 using namespace PBD;
38
39 static void
40 check_nodes (XMLNode const * p, XMLNode const * q, list<string> const & ignore_properties)
41 {
42         CPPUNIT_ASSERT_EQUAL (p->is_content(), q->is_content());
43         if (!p->is_content()) {
44                 CPPUNIT_ASSERT_EQUAL (p->name(), q->name());
45         } else {
46                 CPPUNIT_ASSERT_EQUAL (p->content(), q->content());
47         }
48
49         XMLPropertyList const & pp = p->properties ();
50         XMLPropertyList const & qp = q->properties ();
51         CPPUNIT_ASSERT_EQUAL (pp.size(), qp.size());
52
53         XMLPropertyList::const_iterator i = pp.begin ();
54         XMLPropertyList::const_iterator j = qp.begin ();
55         while (i != pp.end ()) {
56                 CPPUNIT_ASSERT_EQUAL ((*i)->name(), (*j)->name());
57                 if (find (ignore_properties.begin(), ignore_properties.end(), (*i)->name ()) == ignore_properties.end ()) {
58                         CPPUNIT_ASSERT_EQUAL ((*i)->value(), (*j)->value());
59                 }
60                 ++i;
61                 ++j;
62         }
63
64         XMLNodeList const & pc = p->children ();
65         XMLNodeList const & qc = q->children ();
66
67         CPPUNIT_ASSERT_EQUAL (pc.size(), qc.size());
68         XMLNodeList::const_iterator k = pc.begin ();
69         XMLNodeList::const_iterator l = qc.begin ();
70         
71         while (k != pc.end ()) {
72                 check_nodes (*k, *l, ignore_properties);
73                 ++k;
74                 ++l;
75         }
76 }
77
78 void
79 check_xml (XMLNode* node, string ref_file, list<string> const & ignore_properties)
80 {
81         XMLTree ref (ref_file);
82
83         XMLNode* p = node;
84         XMLNode* q = ref.root ();
85
86         check_nodes (p, q, ignore_properties);
87 }
88
89 bool
90 write_ref (XMLNode* node, string ref_file)
91 {
92         XMLTree ref;
93         ref.set_root (node);
94         return ref.write (ref_file);
95 }
96
97 class TestReceiver : public Receiver 
98 {
99 protected:
100         void receive (Transmitter::Channel chn, const char * str) {
101                 const char *prefix = "";
102                 
103                 switch (chn) {
104                 case Transmitter::Error:
105                         prefix = ": [ERROR]: ";
106                         break;
107                 case Transmitter::Info:
108                         /* ignore */
109                         return;
110                 case Transmitter::Warning:
111                         prefix = ": [WARNING]: ";
112                         break;
113                 case Transmitter::Fatal:
114                         prefix = ": [FATAL]: ";
115                         break;
116                 case Transmitter::Throw:
117                         /* this isn't supposed to happen */
118                         abort ();
119                 }
120                 
121                 /* note: iostreams are already thread-safe: no external
122                    lock required.
123                 */
124                 
125                 cout << prefix << str << endl;
126                 
127                 if (chn == Transmitter::Fatal) {
128                         exit (9);
129                 }
130         }
131 };
132
133 TestReceiver test_receiver;
134
135 /** @param dir Session directory.
136  *  @param state Session state file, without .ardour suffix.
137  */
138 Session *
139 load_session (string dir, string state)
140 {
141         SessionEvent::create_per_thread_pool ("test", 512);
142
143         test_receiver.listen_to (error);
144         test_receiver.listen_to (info);
145         test_receiver.listen_to (fatal);
146         test_receiver.listen_to (warning);
147
148         /* We can't use VSTs here as we have a stub instead of the
149            required bits in gtk2_ardour.
150         */
151         Config->set_use_lxvst (false);
152
153         AudioEngine* engine = AudioEngine::create ();
154
155         CPPUNIT_ASSERT (engine->set_default_backend ());
156
157         init_post_engine ();
158
159         CPPUNIT_ASSERT (engine->start () == 0);
160
161         Session* session = new Session (*engine, dir, state);
162         engine->set_session (session);
163         return session;
164 }
165
166 PBD::Searchpath
167 test_search_path ()
168 {
169 #ifdef PLATFORM_WINDOWS
170         std::string wsp(g_win32_get_package_installation_directory_of_module(NULL));
171         return Glib::build_filename (wsp, "ardour_testdata");
172 #else
173         return Glib::getenv("ARDOUR_TEST_PATH");
174 #endif
175 }
176
177 std::string
178 new_test_output_dir (std::string prefix)
179 {
180         std::string tmp_dir = Glib::build_filename (g_get_tmp_dir(), "ardour_test");
181         std::string dir_name;
182         std::string new_test_dir;
183         do {
184                 ostringstream oss;
185                 oss << prefix;
186                 oss << g_random_int ();
187                 dir_name = oss.str();
188                 new_test_dir = Glib::build_filename (tmp_dir, dir_name);
189                 if (Glib::file_test (new_test_dir, Glib::FILE_TEST_EXISTS)) continue;
190         } while (g_mkdir_with_parents (new_test_dir.c_str(), 0755) != 0);
191         return new_test_dir;
192 }
193
194 int
195 get_test_sample_rate ()
196 {
197         return 44100;
198 }