diff --git a/src/scheduler/src/xml/test/ObjectXMLTest.cc b/src/scheduler/src/xml/test/ObjectXMLTest.cc
index 576e25860e..e02a8c25be 100644
--- a/src/scheduler/src/xml/test/ObjectXMLTest.cc
+++ b/src/scheduler/src/xml/test/ObjectXMLTest.cc
@@ -41,6 +41,7 @@ class ObjectXMLTest : public CppUnit::TestFixture
CPPUNIT_TEST( node_constructor );
CPPUNIT_TEST( doc_update );
CPPUNIT_TEST( requirements );
+ CPPUNIT_TEST( rank );
CPPUNIT_TEST_SUITE_END ();
@@ -150,87 +151,160 @@ public:
void requirements()
{
- string host = ""
- "1"
- "ursa12"
- "2"
- "im_kvm"
- "vmm_kvm"
- "tm_nfs"
- "1273799044"
- ""
- " 1"
- " 0"
- " 0"
- " 0"
- " 0"
- " 8194368"
- " 800"
- " 0"
- " 7959232"
- " 800"
- " 0"
- " 523080"
- " 0"
- " 12"
- ""
- ""
- " x86_64"
- " 2326"
- " 800.0"
- " 7959232"
- " ursa12"
- " kvm"
- " Intel(R) Xeon(R) CPU E5410 @ 2.33GHz"
- " 13335836573"
- " 47959"
- " 800"
- " 8194368"
- " 0.0"
- " 523080"
- ""
- "";
-
try
{
ObjectXML obj(host);
- string reqs1 = "NETRX = \"13335836573\"";
- string reqs2 = "NETRX != \"13335836573\"";
+ char* err;
+ bool res;
+ int rc;
- char *err1;
- char *err2;
+ // -----------------------------------------------------------------
+ // REQUIREMENTS MATCHING
+ // -----------------------------------------------------------------
+ string reqs[] =
+ {
+ "TOTALCPU = 800", // exact value matching
+ "TOTALCPU != 800", // Not equal
+ "TOTALCPU > 5", // Greater than expr.
+ "! (TOTALCPU > 5)", // Not exp.
- bool res1;
- bool res2;
+ "HOSTNAME = \"ursa12\"", // Exact string matching
+ "HOSTNAME = \"ursa*\"", // Shell wildcard
+ "HOSTNAME = \"ursa\"",
- int rc1;
- int rc2;
+ "HID = 1",
+ "ARCH = \"*64*\"",
+ "RUNNING_VMS < 100",
- rc1 = obj.eval_bool(reqs1,res1,&err1);
- rc2 = obj.eval_bool(reqs2,res2,&err2);
+ /*
+ // Boolean operators
+ "HOSTNAME = \"ursa*\" & NETRX = \"13335836573\"",
+ // Operator precedence
+ "HOSTNAME = \"ursa*\" | HOSTNAME = \"no\" & HOSTNAME = \"no\"",
+ "( HOSTNAME = \"ursa*\" | HOSTNAME = \"no\" ) & HOSTNAME = \"no\"",
+ //*/
- CPPUNIT_ASSERT(rc1 == 0);
- CPPUNIT_ASSERT(rc2 == 0);
+ "END"
+ };
- CPPUNIT_ASSERT(res1 == true);
- CPPUNIT_ASSERT(res2 == false);
+ bool results[] = { true, false, true, false,
+ true, true, false,
+ true, true, true,
+ /*
+ true, true, false,
+ //*/
+ };
- string rank1 = "RUNNING_VMS";
- string rank2 = "MAX_CPU + NETTX";
+ int i = 0;
+ while( reqs[i] != "END" )
+ {
+// cout << endl << i << " - " << reqs[i];
+ rc = obj.eval_bool( reqs[i], res, &err );
+// cout << "··· rc: " << rc << " result: " << res << " expected: " << results[i] << endl;
+ CPPUNIT_ASSERT( rc == 0 );
+ CPPUNIT_ASSERT( res == results[i] );
- int r1, r2;
+ i++;
+ }
- rc1 = obj.eval_arith(rank1,r1,&err1);
- rc2 = obj.eval_arith(rank2,r2,&err2);
+ // Non-existing attribute compared to string value
+ rc = obj.eval_bool( "FOO = \"BAR\"", res, &err );
+ CPPUNIT_ASSERT( rc == 0 );
+ CPPUNIT_ASSERT( res == false );
- CPPUNIT_ASSERT(rc1 == 0);
- CPPUNIT_ASSERT(rc2 == 0);
-
- CPPUNIT_ASSERT(r1 == 12);
- CPPUNIT_ASSERT(r2 == 47959 + 800 );
+ // Non-existing attribute compared to numeric value
+ rc = obj.eval_bool( "FOO = 123", res, &err );
+ CPPUNIT_ASSERT( rc == 0 );
+ CPPUNIT_ASSERT( res == false );
+ // Existing string attribute compared to numeric value
+ rc = obj.eval_bool( "HOSTNAME = 123 ", res, &err );
+ CPPUNIT_ASSERT( rc == 0 );
+ CPPUNIT_ASSERT( res == false );
+
+ // Existing numeric attribute compared to string value should work
+ rc = obj.eval_bool( "TOTALCPU = \"800\"", res, &err );
+ CPPUNIT_ASSERT( rc == 0 );
+ CPPUNIT_ASSERT( res == true );
+
+ // Bad syntax
+ // TODO: Right now eval_bool returns 1 in case of error, and result
+ // is not set to false.
+ rc = obj.eval_bool( "TOTALCPU ^ * - = abc", res, &err );
+ CPPUNIT_ASSERT( rc != 0 );
+ // CPPUNIT_ASSERT( res == false );
+
+ if (err != 0)
+ {
+ free( err );
+ }
+ }
+ catch(runtime_error& re)
+ {
+ cerr << re.what() << endl;
+ CPPUNIT_ASSERT(1 == 0);
+ }
+ };
+
+
+ void rank()
+ {
+ try
+ {
+ ObjectXML obj(host);
+
+ char* err;
+ int res;
+ int rc;
+
+ // -----------------------------------------------------------------
+ // RANK EXPRESSIONS
+ // -----------------------------------------------------------------
+ string rank_exp[] =
+ {
+ "RUNNING_VMS", // Single attribute
+ "MAX_CPU + NETTX", // Simple operations
+ "RUNNING_VMS * 10", // Operations with fixed values
+ "- FREE_MEM", // Unary operator
+ "2 + 4 * 10", // Operator precedence
+ "(2 + 4) * 10",
+ "END"
+ };
+
+ int results[] =
+ {
+ 12,
+ 47959 + 800,
+ 12 * 10,
+ -7959232,
+ 2 + 4 * 10,
+ (2 + 4) * 10,
+ };
+
+ int i = 0;
+ while( rank_exp[i] != "END" )
+ {
+// cout << endl << i << " - " << rank_exp[i];
+ rc = obj.eval_arith( rank_exp[i], res, &err );
+// cout << "··· rc: " << rc << " res: " << res << " expected: " << results[i] << endl;
+ CPPUNIT_ASSERT( rc == 0 );
+ CPPUNIT_ASSERT( res == results[i] );
+
+ i++;
+ }
+
+
+ // Non-existing attribute
+ rc = obj.eval_arith( "FOO", res, &err );
+ CPPUNIT_ASSERT( rc == 0 );
+ CPPUNIT_ASSERT( res == 0 );
+
+ // Non-existing attribute and operators
+ rc = obj.eval_arith( "FOO + 10", res, &err );
+ CPPUNIT_ASSERT( rc == 0 );
+ CPPUNIT_ASSERT( res == 10 );
}
catch(runtime_error& re)
{
@@ -241,6 +315,7 @@ public:
static const string xml_history_dump;
static const string xml_history_dump2;
+ static const string host;
};
/* ************************************************************************* */
@@ -299,4 +374,46 @@ const string ObjectXMLTest::xml_history_dump2 =
"1_hostname200"
"0000"
"000"
- "";
\ No newline at end of file
+ "";
+
+const string ObjectXMLTest::host =
+ ""
+ "1"
+ "ursa12"
+ "2"
+ "im_kvm"
+ "vmm_kvm"
+ "tm_nfs"
+ "1273799044"
+ ""
+ " 1"
+ " 0"
+ " 0"
+ " 0"
+ " 0"
+ " 8194368"
+ " 800"
+ " 0"
+ " 7959232"
+ " 800"
+ " 0"
+ " 523080"
+ " 0"
+ " 12"
+ ""
+ ""
+ " x86_64"
+ " 2326"
+ " 800.0"
+ " 7959232"
+ " ursa12"
+ " kvm"
+ " Intel(R) Xeon(R) CPU E5410 @ 2.33GHz"
+ " 13335836573"
+ " 47959"
+ " 800"
+ " 8194368"
+ " 0.0"
+ " 523080"
+ ""
+ "";