OLD | NEW |
1 /* | 1 /* |
2 This file is part of the Juju GUI, which lets users view and manage Juju | 2 This file is part of the Juju GUI, which lets users view and manage Juju |
3 environments within a graphical interface (https://launchpad.net/juju-gui). | 3 environments within a graphical interface (https://launchpad.net/juju-gui). |
4 Copyright (C) 2012-2013 Canonical Ltd. | 4 Copyright (C) 2012-2013 Canonical Ltd. |
5 | 5 |
6 This program is free software: you can redistribute it and/or modify it under | 6 This program is free software: you can redistribute it and/or modify it under |
7 the terms of the GNU Affero General Public License version 3, as published by | 7 the terms of the GNU Affero General Public License version 3, as published by |
8 the Free Software Foundation. | 8 the Free Software Foundation. |
9 | 9 |
10 This program is distributed in the hope that it will be useful, but WITHOUT | 10 This program is distributed in the hope that it will be useful, but WITHOUT |
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 assert.isFalse(service.get('exposed')); | 479 assert.isFalse(service.get('exposed')); |
480 var result = fakebackend.unexpose('wordpress'); | 480 var result = fakebackend.unexpose('wordpress'); |
481 assert.isFalse(service.get('exposed')); | 481 assert.isFalse(service.get('exposed')); |
482 assert.isUndefined(result.error); | 482 assert.isUndefined(result.error); |
483 assert.equal( | 483 assert.equal( |
484 'Service "wordpress" is not exposed.', | 484 'Service "wordpress" is not exposed.', |
485 result.warning); | 485 result.warning); |
486 }); | 486 }); |
487 }); | 487 }); |
488 | 488 |
| 489 describe('FakeBackend deployer support', function() { |
| 490 var requires = ['node', |
| 491 'juju-tests-utils', 'juju-models', 'juju-charm-models']; |
| 492 var Y, fakebackend, utils; |
| 493 |
| 494 before(function(done) { |
| 495 Y = YUI(GlobalConfig).use(requires, function(Y) { |
| 496 utils = Y.namespace('juju-tests.utils'); |
| 497 done(); |
| 498 }); |
| 499 }); |
| 500 |
| 501 afterEach(function() { |
| 502 if (fakebackend) { |
| 503 fakebackend.destroy(); |
| 504 } |
| 505 }); |
| 506 |
| 507 it('should support YAML imports', function(done) { |
| 508 utils.promiseImport('data/wp-deployer.yaml') |
| 509 .then(function(resolve) { |
| 510 var result = resolve.result; |
| 511 fakebackend = resolve.backend; |
| 512 assert.equal(result.Error, undefined); |
| 513 assert.equal(result.DeploymentId, 1, |
| 514 'deployment id incorrect'); |
| 515 assert.isNotNull(fakebackend.db.services.getById('wordpress'), |
| 516 'failed to import wordpress'); |
| 517 assert.isNotNull(fakebackend.db.services.getById('mysql'), |
| 518 'failed to import mysql'); |
| 519 assert.equal(fakebackend.db.relations.size(), 1, |
| 520 'failed to import relations'); |
| 521 // Verify units created. |
| 522 assert.equal(fakebackend.db.units.size(), 3, |
| 523 'Unit count wrong'); |
| 524 |
| 525 // Verify config. |
| 526 var wordpress = fakebackend.db.services.getById('wordpress'); |
| 527 assert.equal(wordpress.get('config.engine'), 'nginx'); |
| 528 assert.equal(wordpress.get('config.tuning'), 'single'); |
| 529 done(); |
| 530 }).then(undefined, done); |
| 531 }); |
| 532 |
| 533 it('should provide status of imports', function(done) { |
| 534 utils.promiseImport('data/wp-deployer.yaml') |
| 535 .then(function(resolve) { |
| 536 fakebackend = resolve.backend; |
| 537 fakebackend.statusDeployer( |
| 538 function(status) { |
| 539 assert.lengthOf(status.LastChanges, 1); |
| 540 assert.equal(status.LastChanges[0].Status, 'completed'); |
| 541 assert.equal(status.LastChanges[0].DeploymentId, 1); |
| 542 assert.isNumber(status.LastChanges[0].Timestamp); |
| 543 done(); |
| 544 }); |
| 545 }); |
| 546 }); |
| 547 |
| 548 it('throws an error with more than one import target', function() { |
| 549 fakebackend = utils.makeFakeBackend(); |
| 550 assert.throws(function() { |
| 551 fakebackend.importDeployer({a: {}, b: {}}); |
| 552 }, 'Import target ambigious, aborting.'); |
| 553 }); |
| 554 |
| 555 it('detects service id collisions', function() { |
| 556 fakebackend = utils.makeFakeBackend(); |
| 557 fakebackend.db.services.add({id: 'mysql', charm: 'cs:precise/mysql-26'}); |
| 558 var data = { |
| 559 a: {services: {mysql: { |
| 560 charm: 'cs:precise/mysql-26', |
| 561 num_units: 2, options: {debug: false}}}} |
| 562 }; |
| 563 assert.throws(function() { |
| 564 fakebackend.importDeployer(data); |
| 565 }, 'mysql is already present in the database.'); |
| 566 }); |
| 567 |
| 568 it('properly implements inheritence in target definitions', function(done) { |
| 569 fakebackend = utils.makeFakeBackend(); |
| 570 var data = { |
| 571 a: {services: {mysql: {charm: 'cs:precise/mysql-26', |
| 572 num_units: 2, options: {debug: false}}}}, |
| 573 b: {inherits: 'a', services: {mysql: {num_units: 5, |
| 574 options: {debug: true}}}}, |
| 575 c: {inherits: 'b', services: {mysql: {num_units: 3 }}}, |
| 576 d: {inherits: 'z', services: {mysql: {num_units: 3 }}} |
| 577 }; |
| 578 |
| 579 |
| 580 // No 'z' available. |
| 581 assert.throws(function() { |
| 582 fakebackend.importDeployer(data, 'd'); |
| 583 }, 'Unable to resolve bundle inheritence.'); |
| 584 |
| 585 fakebackend.promiseImport(data, 'c') |
| 586 .then(function() { |
| 587 // Insure that we inherit the debug options from 'b' |
| 588 var mysql = fakebackend.db.services.getById('mysql'); |
| 589 assert.isNotNull(mysql); |
| 590 var config = mysql.get('config'); |
| 591 assert.equal(config['block-size'], 5); |
| 592 done(); |
| 593 }); |
| 594 }); |
| 595 |
| 596 it('properly builds relations on import', function(done) { |
| 597 fakebackend = utils.makeFakeBackend(); |
| 598 var data = { |
| 599 a: { |
| 600 services: { |
| 601 mysql: { |
| 602 charm: 'cs:precise/mysql-26', |
| 603 num_units: 2, options: {debug: false}}, |
| 604 wordpress: { |
| 605 charm: 'cs:precise/wordpress-15', |
| 606 num_units: 1 |
| 607 }}, |
| 608 relations: [['mysql', 'wordpress']] |
| 609 }}; |
| 610 |
| 611 fakebackend.promiseImport(data) |
| 612 .then(function() { |
| 613 var mysql = fakebackend.db.services.getById('mysql'); |
| 614 var wordpress = fakebackend.db.services.getById('wordpress'); |
| 615 assert.isNotNull(mysql); |
| 616 assert.isNotNull(wordpress); |
| 617 |
| 618 var rel = fakebackend.db.relations.item(0); |
| 619 var ep = rel.get('endpoints'); |
| 620 // Validate we got the proper interfaces |
| 621 assert.equal(ep[0][0], 'wordpress'); |
| 622 assert.equal(ep[0][1].name, 'db'); |
| 623 assert.equal(ep[1][0], 'mysql'); |
| 624 assert.equal(ep[1][1].name, 'db'); |
| 625 assert.isFalse(rel.get('pending')); |
| 626 done(); |
| 627 }).then(undefined, function(e) {done(e);}); |
| 628 }); |
| 629 |
| 630 it('should support finding charms through a search', function(done) { |
| 631 // Use import to import many charms and then resolve them with a few |
| 632 // different keys. |
| 633 var defaultSeries = 'precise'; |
| 634 utils.promiseImport('data/blog.yaml', 'wordpress-prod') |
| 635 .then(function(resolve) { |
| 636 var db = resolve.backend.db; |
| 637 assert.isNotNull(db.charms.find('wordpress', defaultSeries)); |
| 638 assert.isNotNull(db.charms.find('precise/wordpress', |
| 639 defaultSeries)); |
| 640 assert.isNotNull(db.charms.find('precise/wordpress')); |
| 641 assert.isNotNull(db.charms.find('cs:precise/wordpress')); |
| 642 assert.isNotNull(db.charms.find('cs:precise/wordpress-999')); |
| 643 // Can't find this w/o a series |
| 644 assert.isNull(db.charms.find('wordpress')); |
| 645 // Find fails on missing items as well. |
| 646 assert.isNull(db.charms.find('foo')); |
| 647 assert.isNull(db.charms.find('foo', defaultSeries)); |
| 648 done(); |
| 649 }).then(undefined, done); |
| 650 }); |
| 651 }); |
| 652 |
489 describe('FakeBackend.uniformOperations', function() { | 653 describe('FakeBackend.uniformOperations', function() { |
490 var requires = ['node', | 654 var requires = ['node', |
491 'juju-tests-utils', 'juju-models', 'juju-charm-models']; | 655 'juju-tests-utils', 'juju-models', 'juju-charm-models']; |
492 var Y, fakebackend, utils; | 656 var Y, fakebackend, utils; |
493 | 657 |
494 before(function(done) { | 658 before(function(done) { |
495 Y = YUI(GlobalConfig).use(requires, function(Y) { | 659 Y = YUI(GlobalConfig).use(requires, function(Y) { |
496 utils = Y.namespace('juju-tests.utils'); | 660 utils = Y.namespace('juju-tests.utils'); |
497 done(); | 661 done(); |
498 }); | 662 }); |
499 }); | 663 }); |
500 | 664 |
501 beforeEach(function() { | 665 beforeEach(function() { |
502 fakebackend = utils.makeFakeBackend(); | 666 fakebackend = utils.makeFakeBackend(); |
503 }); | 667 }); |
504 | 668 |
505 afterEach(function() { | 669 afterEach(function() { |
506 fakebackend.destroy(); | 670 fakebackend.destroy(); |
507 }); | 671 }); |
508 | 672 |
509 function createRelation(charms, relation, mock, done, callback) { | |
510 fakebackend.deploy(charms[0], function() { | |
511 fakebackend.deploy(charms[1], function() { | |
512 relation.push(true); | |
513 var result = fakebackend.addRelation.apply(fakebackend, relation); | |
514 assert.equal(result.error, undefined); | |
515 assert.equal(result.relationId, 'relation-0'); | |
516 assert.equal(typeof result.relation, 'object'); | |
517 assert.deepEqual(result.endpoints, mock.endpoints); | |
518 assert.equal(result.scope, mock.scope); | |
519 assert.equal(result.type, mock.type); | |
520 callback(result, done); | |
521 }); | |
522 }); | |
523 } | |
524 | |
525 describe('FakeBackend.exportEnvironment', function(done) { | |
526 | |
527 it('rejects unauthenticated calls', function() { | |
528 fakebackend.logout(); | |
529 var result = fakebackend.exportEnvironment(); | |
530 assert.equal(result.error, 'Please log in.'); | |
531 }); | |
532 | |
533 it('successfully exports env data', function(done) { | |
534 createRelation( | |
535 ['cs:precise/wordpress-15', 'cs:mysql'], | |
536 ['wordpress:db', 'mysql:db'], | |
537 { type: 'mysql', scope: 'global', | |
538 endpoints: | |
539 [['wordpress', {name: 'db'}], ['mysql', {name: 'db'}]]}, | |
540 done, | |
541 function(result, done) { | |
542 var data = fakebackend.exportEnvironment().result; | |
543 assert.equal(data.meta.exportFormat, 1.0); | |
544 assert.equal(data.services[0].name, 'wordpress'); | |
545 assert.equal(data.relations[0].display_name, 'db'); | |
546 done(); | |
547 }); | |
548 }); | |
549 }); | |
550 | |
551 describe('FakeBackend deployer support', function() { | |
552 | |
553 it('should support YAML imports', function(done) { | |
554 fakebackend.db.environment.set('defaultSeries', 'precise'); | |
555 fakebackend.importDeployer( | |
556 utils.loadFixture('data/wp-deployer.yaml'), | |
557 'wordpress-prod', function(result) { | |
558 assert.equal(result.Error, undefined); | |
559 assert.equal(result.DeploymentId, 1, 'deployment id incorrect'); | |
560 assert.isNotNull(fakebackend.db.services.getById('wordpress'), | |
561 'failed to import wordpress'); | |
562 assert.isNotNull(fakebackend.db.services.getById('mysql'), | |
563 'failed to import mysql'); | |
564 assert.equal(fakebackend.db.relations.size(), 1, | |
565 'failed to import relations'); | |
566 done(); | |
567 }); | |
568 | |
569 }); | |
570 | |
571 it('should provide status of imports', function(done) { | |
572 fakebackend.db.environment.set('defaultSeries', 'precise'); | |
573 fakebackend.importDeployer( | |
574 utils.loadFixture('data/wp-deployer.yaml'), | |
575 'wordpress-prod', function() { | |
576 fakebackend.statusDeployer( | |
577 function(status) { | |
578 assert.lengthOf(status.LastChanges, 1); | |
579 assert.equal(status.LastChanges[0].Status, 'completed'); | |
580 assert.equal(status.LastChanges[0].DeploymentId, 1); | |
581 assert.isNumber(status.LastChanges[0].Timestamp); | |
582 done(); | |
583 }); | |
584 }); | |
585 }); | |
586 | |
587 | |
588 }); | |
589 | |
590 describe('FakeBackend.importEnvironment', function(done) { | |
591 it('rejects unauthenticated calls', function(done) { | |
592 fakebackend.logout(); | |
593 var result = fakebackend.importEnvironment('', function(result) { | |
594 assert.equal(result.error, 'Please log in.'); | |
595 done(); | |
596 }); | |
597 }); | |
598 | |
599 it('successfully imports v0 data', function(done) { | |
600 var fixture = utils.loadFixture('data/sample-improv.json', false); | |
601 fakebackend.importEnvironment(fixture, function(result) { | |
602 assert.isTrue(result.result); | |
603 assert.isNotNull(fakebackend.db.services.getById('wordpress')); | |
604 | |
605 // Verify that the charms have been loaded. | |
606 assert.isNotNull(fakebackend.db.charms.getById( | |
607 'cs:precise/wordpress-15')); | |
608 done(); | |
609 }); | |
610 }); | |
611 | |
612 it('successfully imports v1 data', function(done) { | |
613 var fixture = utils.loadFixture('data/sample-fakebackend.json', false); | |
614 fakebackend.importEnvironment(fixture, function(result) { | |
615 assert.isTrue(result.result); | |
616 assert.isNotNull(fakebackend.db.services.getById('wordpress')); | |
617 done(); | |
618 }); | |
619 }); | |
620 }); | |
621 | |
622 | |
623 describe('FakeBackend.resolved', function(done) { | 673 describe('FakeBackend.resolved', function(done) { |
624 | 674 |
625 it('rejects unauthenticated calls', function() { | 675 it('rejects unauthenticated calls', function() { |
626 fakebackend.logout(); | 676 fakebackend.logout(); |
627 var result = fakebackend.resolved('wordpress/0'); | 677 var result = fakebackend.resolved('wordpress/0'); |
628 assert.equal(result.error, 'Please log in.'); | 678 assert.equal(result.error, 'Please log in.'); |
629 }); | 679 }); |
630 | 680 |
631 it('reports invalid untis', function() { | 681 it('reports invalid untis', function() { |
632 var result = fakebackend.resolved('wordpress/0'); | 682 var result = fakebackend.resolved('wordpress/0'); |
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1164 fakebackend = utils.makeFakeBackend(); | 1214 fakebackend = utils.makeFakeBackend(); |
1165 deployResult = undefined; | 1215 deployResult = undefined; |
1166 callback = function(response) { deployResult = response; }; | 1216 callback = function(response) { deployResult = response; }; |
1167 }); | 1217 }); |
1168 | 1218 |
1169 afterEach(function() { | 1219 afterEach(function() { |
1170 fakebackend.destroy(); | 1220 fakebackend.destroy(); |
1171 }); | 1221 }); |
1172 | 1222 |
1173 function createRelation(charms, relation, mock, done) { | 1223 function createRelation(charms, relation, mock, done) { |
1174 fakebackend.deploy(charms[0], function() { | 1224 fakebackend.promiseDeploy(charms[0]) |
1175 fakebackend.deploy(charms[1], function() { | 1225 .then(fakebackend.promiseDeploy(charms[1])) |
1176 relation.push(true); | 1226 .then(function() { |
1177 var result = fakebackend.addRelation.apply(fakebackend, relation); | 1227 relation.push(true); |
1178 assert.equal(result.error, undefined); | 1228 var result = fakebackend.addRelation.apply(fakebackend, relation); |
1179 assert.equal(result.relationId, 'relation-0'); | 1229 assert.equal(result.error, undefined); |
1180 assert.equal(typeof result.relation, 'object'); | 1230 assert.equal(result.relationId, 'relation-0'); |
1181 assert.deepEqual(result.endpoints, mock.endpoints); | 1231 assert.equal(typeof result.relation, 'object'); |
1182 assert.equal(result.scope, mock.scope); | 1232 // Check those elements we care about. |
1183 assert.equal(result.type, mock.type); | 1233 assert.equal(result.endpoints[0][0], mock.endpoints[0][0]); |
1184 done(); | 1234 assert.equal(result.endpoints[0][1].name, |
1185 }); | 1235 mock.endpoints[0][1].name); |
1186 }); | 1236 assert.equal(result.endpoints[1][0], mock.endpoints[1][0]); |
| 1237 assert.equal(result.endpoints[1][1].name, |
| 1238 mock.endpoints[1][1].name); |
| 1239 assert.equal(result.scope, mock.scope); |
| 1240 assert.equal(result.type, mock.type); |
| 1241 done(); |
| 1242 }).then(undefined, done); |
1187 } | 1243 } |
1188 | 1244 |
1189 it('rejects unauthenticated calls', function() { | 1245 it('rejects unauthenticated calls', function() { |
1190 fakebackend.logout(); | 1246 fakebackend.logout(); |
1191 var result = fakebackend.addRelation(); | 1247 var result = fakebackend.addRelation(); |
1192 assert.equal(result.error, 'Please log in.'); | 1248 assert.equal(result.error, 'Please log in.'); |
1193 }); | 1249 }); |
1194 | 1250 |
1195 it('requires two string endpoint names', function() { | 1251 it('requires two string endpoint names', function() { |
1196 var result = fakebackend.addRelation(); | 1252 var result = fakebackend.addRelation(); |
(...skipping 27 matching lines...) Expand all Loading... |
1224 fakebackend.deploy('cs:precise/wordpress-15', function() { | 1280 fakebackend.deploy('cs:precise/wordpress-15', function() { |
1225 fakebackend.deploy('cs:precise/haproxy-18', function() { | 1281 fakebackend.deploy('cs:precise/haproxy-18', function() { |
1226 var result = fakebackend.addRelation( | 1282 var result = fakebackend.addRelation( |
1227 'wordpress:cache', 'haproxy:munin'); | 1283 'wordpress:cache', 'haproxy:munin'); |
1228 assert.equal(result.error, 'Specified relation is unavailable.'); | 1284 assert.equal(result.error, 'Specified relation is unavailable.'); |
1229 done(); | 1285 done(); |
1230 }); | 1286 }); |
1231 }); | 1287 }); |
1232 }); | 1288 }); |
1233 | 1289 |
1234 it('can create a relation with a double explicit interface', | 1290 it('can create a relation with a explicit interfaces', function(done) { |
1235 function(done) { | 1291 createRelation( |
1236 createRelation( | 1292 ['cs:wordpress', 'cs:mysql'], |
1237 ['cs:wordpress', 'cs:mysql'], | 1293 ['wordpress:db', 'mysql:db'], |
1238 ['wordpress:db', 'mysql:db'], | 1294 { type: 'mysql', scope: 'global', |
1239 { type: 'mysql', scope: 'global', | 1295 endpoints: |
1240 endpoints: | 1296 [['wordpress', {name: 'db'}], ['mysql', {name: 'db'}]]}, |
1241 [['wordpress', {name: 'db'}], ['mysql', {name: 'db'}]]}, | 1297 done); |
1242 done); | 1298 }); |
1243 }); | |
1244 | 1299 |
1245 it('can create a relation with double explicit interface (reverse)', | 1300 it('can create a relation with double explicit interface (reverse)', |
1246 function(done) { | 1301 function(done) { |
1247 createRelation( | 1302 createRelation( |
1248 ['cs:wordpress', 'cs:mysql'], | 1303 ['cs:wordpress', 'cs:mysql'], |
1249 ['mysql:db', 'wordpress:db'], | 1304 ['mysql:db', 'wordpress:db'], |
1250 { type: 'mysql', scope: 'global', | 1305 { type: 'mysql', scope: 'global', |
1251 endpoints: | 1306 endpoints: |
1252 [['wordpress', {name: 'db'}], ['mysql', {name: 'db'}]]}, | 1307 [['wordpress', {name: 'db'}], ['mysql', {name: 'db'}]]}, |
1253 done); | 1308 done); |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1518 ['cs:wordpress', 'cs:mysql'], | 1573 ['cs:wordpress', 'cs:mysql'], |
1519 ['wordpress:db', 'mysql:db'], | 1574 ['wordpress:db', 'mysql:db'], |
1520 ['wordpress:bar', 'mysql:baz'], | 1575 ['wordpress:bar', 'mysql:baz'], |
1521 {error: 'Relationship does not exist'}, | 1576 {error: 'Relationship does not exist'}, |
1522 done); | 1577 done); |
1523 }); | 1578 }); |
1524 | 1579 |
1525 }); | 1580 }); |
1526 | 1581 |
1527 })(); | 1582 })(); |
OLD | NEW |