File:
[LON-CAPA] /
loncom /
metadata_database /
lonmetadata_test.pl
Revision
1.5:
download - view:
text,
annotated -
select for diffs
Fri Jun 11 19:52:12 2004 UTC (20 years, 8 months ago) by
matthew
Branches:
MAIN
CVS tags:
version_2_9_X,
version_2_9_99_0,
version_2_9_1,
version_2_9_0,
version_2_8_X,
version_2_8_99_1,
version_2_8_99_0,
version_2_8_2,
version_2_8_1,
version_2_8_0,
version_2_7_X,
version_2_7_99_1,
version_2_7_99_0,
version_2_7_1,
version_2_7_0,
version_2_6_X,
version_2_6_99_1,
version_2_6_99_0,
version_2_6_3,
version_2_6_2,
version_2_6_1,
version_2_6_0,
version_2_5_X,
version_2_5_99_1,
version_2_5_99_0,
version_2_5_2,
version_2_5_1,
version_2_5_0,
version_2_4_X,
version_2_4_99_0,
version_2_4_2,
version_2_4_1,
version_2_4_0,
version_2_3_X,
version_2_3_99_0,
version_2_3_2,
version_2_3_1,
version_2_3_0,
version_2_2_X,
version_2_2_99_1,
version_2_2_99_0,
version_2_2_2,
version_2_2_1,
version_2_2_0,
version_2_1_X,
version_2_1_99_3,
version_2_1_99_2,
version_2_1_99_1,
version_2_1_99_0,
version_2_1_3,
version_2_1_2,
version_2_1_1,
version_2_1_0,
version_2_12_X,
version_2_11_X,
version_2_11_6_msu,
version_2_11_6,
version_2_11_5_msu,
version_2_11_5,
version_2_11_4_uiuc,
version_2_11_4_msu,
version_2_11_4,
version_2_11_3_uiuc,
version_2_11_3_msu,
version_2_11_3,
version_2_11_2_uiuc,
version_2_11_2_msu,
version_2_11_2_educog,
version_2_11_2,
version_2_11_1,
version_2_11_0_RC3,
version_2_11_0_RC2,
version_2_11_0_RC1,
version_2_11_0,
version_2_10_X,
version_2_10_1,
version_2_10_0_RC2,
version_2_10_0_RC1,
version_2_10_0,
version_2_0_X,
version_2_0_99_1,
version_2_0_2,
version_2_0_1,
version_2_0_0,
version_1_99_3,
version_1_99_2,
version_1_99_1_tmcc,
version_1_99_1,
version_1_99_0_tmcc,
version_1_99_0,
version_1_3_X,
version_1_3_3,
version_1_3_2,
version_1_3_1,
version_1_3_0,
version_1_2_X,
version_1_2_99_1,
version_1_2_99_0,
version_1_2_1,
version_1_2_0,
version_1_1_99_5,
version_1_1_99_4,
version_1_1_99_3,
version_1_1_99_2,
version_1_1_99_1,
loncapaMITrelate_1,
language_hyphenation_merge,
language_hyphenation,
bz6209-base,
bz6209,
bz5969,
bz2851,
PRINT_INCOMPLETE_base,
PRINT_INCOMPLETE,
HEAD,
GCI_3,
GCI_2,
GCI_1,
BZ5971-printing-apage,
BZ5434-fox,
BZ4492-merge,
BZ4492-feature_horizontal_radioresponse
lonmetadata:
Minor changes to &store_metadata, should be a little more readable now.
&lookup_metadata: added $tablename input parameter, defaults to 'metadata'.
Implemented &delete_metadata
Added &update_metadata
lonmetadata_test.pl:
Added tests for &lookup_metadata, &delete_metadata, and &update_metadata
Added utility routines &metadata_do_not_match, &metadata_mismatch_error,
&testrecords, &build_test_table.
1: #!/usr/bin/perl -w
2: # The LearningOnline Network with CAPA
3: #
4: # $Id: lonmetadata_test.pl,v 1.5 2004/06/11 19:52:12 matthew Exp $
5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
28: ######################################################################
29: use strict;
30:
31: use DBI;
32: use LONCAPA::lonmetadata();
33: use Test::Simple tests => 7;
34:
35: ##
36: ## Note: The root password to my MySQL server is shown below.
37: ## Access is only allowed from localhost so it should be okay.
38: ## Now if you will excuse me I have to change the password on my luggage.
39: ##
40: my $supersecretpassword = '123'; # shhhh
41:
42: ok(&create_test_db(),'database creation');
43: ok(&test_creation(),'table creation');
44: ok(&test_named_creation(),'named table creation');
45: ok(&test_inserts(),'insert test');
46: ok(&test_retrieval(),'retrieval test');
47: ok(&test_delete(),'delete test');
48: ok(&test_update(),'update test');
49:
50: exit;
51:
52: #####################################################################
53: #####################################################################
54: ##
55: ## Tests live down below
56: ##
57: #####################################################################
58: #####################################################################
59: sub create_test_db {
60: my $dbh = DBI->connect("DBI:mysql:test","root",$supersecretpassword,
61: { RaiseError =>0,PrintError=>0});
62: if (! defined($dbh)) {
63: return 0;
64: }
65: my $request = 'DROP DATABASE IF EXISTS lonmetatest';
66: $dbh->do($request);
67: $request = 'CREATE DATABASE lonmetatest';
68: $dbh->do($request);
69: if ($dbh->err) {
70: return 0;
71: } else {
72: return 1;
73: }
74: $dbh->disconnect();
75: }
76:
77: sub test_creation {
78: my $dbh = DBI->connect("DBI:mysql:lonmetatest","root",$supersecretpassword,
79: { RaiseError =>0,PrintError=>0});
80: my $request = &LONCAPA::lonmetadata::create_metadata_storage();
81: $dbh->do($request);
82: if ($dbh->err) {
83: $dbh->disconnect();
84: return 0;
85: } else {
86: $dbh->disconnect();
87: return 1;
88: }
89: }
90:
91: sub test_named_creation {
92: my $request =
93: &LONCAPA::lonmetadata::create_metadata_storage('nonmetadata');
94: my $dbh = DBI->connect("DBI:mysql:lonmetatest","root",$supersecretpassword,
95: { RaiseError =>0,PrintError=>0});
96: $dbh->do($request); # Create the table, only return 0 if we cannot.
97: if ($dbh->err) {
98: $dbh->disconnect();
99: return 0;
100: }
101: $dbh->do('DROP TABLE nonmetadata'); # This will generate an error if the
102: # table does not exist
103: if ($dbh->err) {
104: $dbh->disconnect();
105: return 0;
106: }
107: return 1;
108: }
109:
110: sub test_inserts {
111: my @TestRecords = &testrecords();
112: my $tablename = 'metadatatest';
113: my $dbh = DBI->connect("DBI:mysql:lonmetatest","root",$supersecretpassword,
114: { RaiseError =>1,PrintError=>1});
115: # Create the table
116: my $request = &LONCAPA::lonmetadata::create_metadata_storage($tablename);
117: $dbh->do($request);
118: if ($dbh->err) {
119: $dbh->disconnect();
120: warn "Unable to create table for test";
121: return 0;
122: }
123: # Store the sample records
124: foreach my $data (@TestRecords) {
125: my ($count,$error) = &LONCAPA::lonmetadata::store_metadata($dbh,
126: $tablename,
127: $data);
128: if (! $count) {
129: warn $error;
130: return 0;
131: }
132: }
133: $dbh->do('DROP TABLE '.$tablename);
134: $dbh->disconnect();
135: return 1;
136: }
137:
138: sub test_retrieval {
139: &LONCAPA::lonmetadata::clear_sth();
140: my $tablename = 'metadatatest';
141: my $dbh = DBI->connect("DBI:mysql:lonmetatest","root",$supersecretpassword,
142: { RaiseError =>0,PrintError=>0});
143: if (! &build_test_table($dbh,$tablename)) {
144: warn "Unable to build test table\n";
145: return 0;
146: }
147: # Retrieve records
148: my $count=0;
149: my @TestRecords = &testrecords();
150: foreach my $data (@TestRecords) {
151: my ($error,$row) = &LONCAPA::lonmetadata::lookup_metadata
152: ($dbh,' url='.$dbh->quote($data->{'url'}),
153: undef,$tablename);
154: if ($error) {
155: warn "Retrieval error for item $count\n";
156: return 0;
157: }
158: my %fromdb = &LONCAPA::lonmetadata::metadata_col_to_hash(@{$row->[0]});
159: if (&metadata_do_not_match($data,\%fromdb)) {
160: warn(&metadata_mismatch_error.$/);
161: return 0;
162: }
163: $count++;
164: }
165: #
166: $dbh->do('DROP TABLE '.$tablename);
167: $dbh->disconnect();
168: return 1;
169: }
170:
171: sub test_delete {
172: my $tablename = 'metadatatest';
173: my $dbh = DBI->connect("DBI:mysql:lonmetatest","root",$supersecretpassword,
174: { RaiseError =>0,PrintError=>0});
175: if (! &build_test_table($dbh,$tablename)) {
176: return 0;
177: }
178: my @TestRecords = &testrecords();
179: foreach my $record (@TestRecords) {
180: my $error = &LONCAPA::lonmetadata::delete_metadata($dbh,$tablename,
181: $record->{'url'});
182: if ($error) {
183: warn $error;
184: return 0;
185: }
186: # Verify delete has taken place
187: my $row;
188: ($error,$row) = &LONCAPA::lonmetadata::lookup_metadata
189: ($dbh,' url='.$dbh->quote($record->{'url'}),
190: undef,$tablename);
191: if (defined($row) && ref($row) eq 'ARRAY' && defined($row->[0])) {
192: # We retrieved the record we just deleted. This is BAD.
193: return 1;
194: }
195: }
196: $dbh->do('DROP TABLE '.$tablename);
197: $dbh->disconnect();
198: return 1;
199: }
200:
201: sub test_update {
202: my $tablename = 'metadatatest';
203: my $dbh = DBI->connect("DBI:mysql:lonmetatest","root",$supersecretpassword,
204: { RaiseError =>0,PrintError=>0});
205: if (! &build_test_table($dbh,$tablename)) {
206: return 0;
207: }
208: my @TestRecords = &testrecords();
209: foreach my $record (@TestRecords) {
210: $record->{'title'}.= 'newtitle';
211: my $error = &LONCAPA::lonmetadata::update_metadata
212: ($dbh,$tablename,
213: { url => $record->{'url'},
214: title => $record->{'title'} });
215: if ($error) {
216: warn $error.$/;
217: return 0;
218: }
219: my $row;
220: ($error,$row) = &LONCAPA::lonmetadata::lookup_metadata
221: ($dbh,' url='.$dbh->quote($record->{'url'}),
222: undef,$tablename);
223: if ($error) {
224: warn $error.$/;
225: return 0;
226: }
227: my %fromdb = &LONCAPA::lonmetadata::metadata_col_to_hash(@{$row->[0]});
228: if (&metadata_do_not_match($record,\%fromdb)) {
229: warn(&metadata_mismatch_error.$/);
230: return 0;
231: }
232: }
233: #
234: # Now test by updating a resource that does not have an entry.
235: my @NewThings = (
236: { url => 'm/b/h/test100' },
237: { url => "m/b/h/t'e\"st101" },
238: { title => 'test document 102',
239: author => 'matthew',
240: subject => 'subject 1',
241: url => 'm/b/h/test102',
242: keywords => 'key word',
243: version => '1.4',
244: notes => 'note note note',
245: abstract => 'probably' },);
246: foreach my $record (@NewThings) {
247: print "testing ".$record->{'url'}.$/;
248: my $error = &LONCAPA::lonmetadata::update_metadata
249: ($dbh,$tablename,$record);
250: if ($error) {
251: warn $error.$/;
252: return 0;
253: }
254: my $row;
255: ($error,$row) = &LONCAPA::lonmetadata::lookup_metadata
256: ($dbh,' url='.$dbh->quote($record->{'url'}),
257: undef,$tablename);
258: if ($error) {
259: warn $error.$/;
260: return 0;
261: }
262: my %fromdb = &LONCAPA::lonmetadata::metadata_col_to_hash(@{$row->[0]});
263: if (&metadata_do_not_match($record,\%fromdb)) {
264: warn(&metadata_mismatch_error.$/);
265: return 0;
266: }
267: }
268: $dbh->do('DROP TABLE '.$tablename);
269: $dbh->disconnect();
270: return 1;
271: }
272:
273: ##################################################################
274: ##################################################################
275: sub build_test_table {
276: my ($dbh,$tablename) = @_;
277: &LONCAPA::lonmetadata::clear_sth();
278: if (! defined($tablename)) {
279: warn "No table name specified in build_test_table.\n";
280: return 0;
281: }
282: my @TestRecords = &testrecords();
283: # Create the table
284: my $request = &LONCAPA::lonmetadata::create_metadata_storage($tablename);
285: $dbh->do($request);
286: if ($dbh->err) {
287: $dbh->disconnect();
288: warn "Unable to create table for test";
289: return 0;
290: }
291: # Store the sample records
292: foreach my $data (@TestRecords) {
293: my ($count,$error) = &LONCAPA::lonmetadata::store_metadata($dbh,
294: $tablename,
295: $data);
296: if (! $count) {
297: warn $error;
298: return 0;
299: }
300: }
301: return 1;
302: }
303:
304: ##################################################################
305: ##################################################################
306: sub testrecords {
307: return (
308: { url => 'm/b/h/test1' },
309: { url => "m/b/h/t'e\"st1" },
310: { title => 'test document 1',
311: author => 'matthew',
312: subject => 'subject 1',
313: url => 'm/b/h/test2',
314: keywords => 'key word',
315: version => '1.4',
316: notes => 'note note note',
317: abstract => 'probably',
318: mime => 'none',
319: language => 'english',
320: creationdate =>'',
321: lastrevisiondate =>'',
322: owner => 'hallmat3',
323: copyright => 'default',
324: dependencies => undef,
325: modifyinguser => 'hallmat3',
326: authorspace => 'hallmat3',
327: lowestgradelevel =>'1',
328: highestgradelevel => 16,
329: standards => 'Delaware Required Instruction Program',
330: count => '2544444',
331: course => '4',
332: course_list => 'course 1, course 2, course 3, course 4',
333: goto => '1',
334: goto_list =>'m/b/h/test1',
335: comefrom => '0',
336: comefrom_list =>'',
337: sequsage => '1',
338: sequsage_list =>'mbhtest.sequence',
339: stdno => '0',
340: stdno_list => '',
341: avetries => '0.0',
342: avetries_list =>'',
343: difficulty =>'',
344: difficulty_list => '',
345: clear => '5',
346: technical => '4',
347: correct => '3',
348: helpful => '2',
349: depth => '5',
350: hostname =>'6',
351: },
352: );
353: }
354:
355: ##################################################################
356: ##################################################################
357: {
358:
359: my $error;
360:
361: sub metadata_do_not_match {
362: my ($orig,$fromdb) = @_;
363: my %checkedfields;
364: my $url = $orig->{'url'};
365: foreach my $field (keys(%$orig)){
366: #
367: # Make sure the field exists
368: if (! exists($fromdb->{$field})) {
369: $error = 'url='.$url.': field '.$field.' missing.';
370: return 1;
371: }
372: #
373: # Make sure each field matches
374: my ($old,$new) = ($orig->{$field},$fromdb->{$field});
375: if (! defined($new) && ! defined($old)) {
376: next;
377: } elsif (! defined($new) && defined($old)){
378: if ($old eq '') {
379: next; # This is okay, we treat undef and '' equivalently.
380: } else {
381: $error = 'url='.$url.' mismatch on '.$field.$/;
382: $error .= 'old="'.$orig->{'field'}.'" new=undef'.$/;
383: return 1;
384: }
385: } elsif (defined($new) && ! defined($old)) {
386: if ($new eq '') {
387: next; # This is okay, we treat undef and '' equivalently.
388: } else {
389: $error = 'url='.$url.' mismatch on '.$field.$/;
390: $error .= 'old=undef new="'.$new.'"'.$/;
391: return 1;
392: }
393: } elsif (($old ne $new)) {
394: if ($field =~ /date$/ && $old eq '' &&
395: $new eq '0000-00-00 00:00:00') {
396: # '' is the same as '0' for dates
397: next;
398: }
399: if ($old =~ /\d*\.?\d*/) {
400: next if (abs($old - $new) < 0.000001);
401: }
402: #
403: $error = 'url='.$url.' mismatch on '.$field.$/;
404: $error .= 'old="'.$old.'" new="'.$new.'"';
405: return 1;
406: }
407: #
408: $checkedfields{$field}++;
409: }
410: foreach my $k (keys(%{$fromdb})) {
411: next if (exists($checkedfields{$k}));
412: next if (! defined($fromdb->{$k}));
413: next if ($fromdb->{$k} eq '' ||
414: $fromdb->{$k} eq '0' ||
415: $fromdb->{$k} eq '0000-00-00 00:00:00');
416: $error = 'new has field '.$k.' which old does not have. '.
417: 'value = '.$fromdb->{$k};
418: return 1;
419: }
420: return 0;
421: }
422:
423: sub metadata_mismatch_error {
424: return $error;
425: }
426:
427: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>