public void Generate_InvalidRuleFileSpecified_GeneratorError()
        {
            // Arrange
            var outputDir = TestUtils.CreateTestDirectory(this.TestContext, ".out");

            var logger = new TestLogger();

            var remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);

            CreatePackageInFakeRemoteRepo(remoteRepoBuilder, "dummy.id", "1.1");

            var nuGetHandler = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, GetLocalNuGetDownloadDir(), logger);

            // Create an invalid rule file
            var dummyRuleFilePath = Path.Combine(outputDir, "invalidRule.xml");

            File.WriteAllText(dummyRuleFilePath, "not valid xml");

            AnalyzerPluginGenerator apg = new AnalyzerPluginGenerator(nuGetHandler, logger);

            var args = new ProcessedArgsBuilder("dummy.id", outputDir)
                       .SetLanguage("cs")
                       .SetPackageVersion("1.1")
                       .SetRuleFilePath(dummyRuleFilePath)
                       .Build();

            // Act
            bool result = apg.Generate(args);

            // Assert
            result.Should().BeFalse();
            AssertRuleTemplateDoesNotExist(outputDir);
            logger.AssertSingleErrorExists("invalidRule.xml"); // expecting an error containing the invalid rule file name
        }
        public void GetDependencies_DependenciesNotInstalledLocally_Warning()
        {
            // Arrange
            string            targetNuGetRoot   = TestUtils.CreateTestDirectory(TestContext, ".nuget.target");
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(TestContext);
            string            dummyContentFile  = CreateDummyContentFile();

            IEnumerable <IPackage> actualDependencies;

            // Build a dependency graph: "main" depends on "dependency"
            IPackage dependencyPackage = remoteRepoBuilder.CreatePackage("dependency.package.id", "1.2", dummyContentFile, RemoteRepoBuilder.License.Required /* no dependencies */);
            IPackage mainPackage       = remoteRepoBuilder.CreatePackage("a", "2.0", dummyContentFile, RemoteRepoBuilder.License.NotRequired, dependencyPackage);

            // 1. Dependencies have not been installed locally -> warning but no error
            TestLogger          logger      = new TestLogger();
            NuGetPackageHandler testSubject = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, targetNuGetRoot, logger);

            actualDependencies = testSubject.GetInstalledDependencies(mainPackage);
            AssertExpectedPackageIds(actualDependencies /* no dependencies resolved*/);

            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(1);
            logger.AssertSingleWarningExists("dependency.package.id");

            // 2. Now install the package -> dependencies should resolve ok
            logger      = new TestLogger();
            testSubject = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, targetNuGetRoot, logger);

            testSubject.FetchPackage(mainPackage.Id, mainPackage.Version);
            actualDependencies = testSubject.GetInstalledDependencies(mainPackage);
            AssertExpectedPackageIds(actualDependencies, "dependency.package.id");

            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(0);
        }
        public void Generate_LicenseAcceptanceNotRequestedIfNoAnalysers()
        {
            // No point in asking the user to accept licenses for packages that don't contain analyzers

            // Arrange
            string outputDir        = TestUtils.CreateTestDirectory(TestContext, ".out");
            string dummyContentFile = TestUtils.CreateTextFile("dummy.txt", outputDir, "non-analyzer content file");

            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(TestContext);

            // Parent only: requires license
            remoteRepoBuilder.CreatePackage("non-analyzer.requireAccept.id", "1.0", dummyContentFile, License.Required);

            TestLogger logger           = new TestLogger();
            AnalyzerPluginGenerator apg = CreateTestSubjectWithFakeRemoteRepo(remoteRepoBuilder, logger);

            // 1. User does not accept, but no analyzers so no license prompt -> fails due absence of analyzers
            ProcessedArgs args = CreateArgs("non-analyzer.requireAccept.id", "1.0", "cs", false /* accept licenses */,
                                            false, outputDir);
            bool result = apg.Generate(args);

            result.Should().BeFalse("Expecting generator to fail");

            logger.AssertSingleWarningExists(String.Format(UIResources.APG_NoAnalyzersFound, "non-analyzer.requireAccept.id"));
            logger.AssertSingleWarningExists(UIResources.APG_NoAnalyzersInTargetSuggestRecurse);
            logger.AssertWarningsLogged(2);
            logger.AssertErrorsLogged(0);
        }
Esempio n. 4
0
        public void Generate_ValidSqaleFileSpecified_TemplateFileNotCreated()
        {
            // Arrange
            string outputDir = TestUtils.CreateTestDirectory(this.TestContext, ".out");

            RemoteRepoBuilder       remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);
            AnalyzerPluginGenerator apg = CreateTestSubjectWithFakeRemoteRepo(remoteRepoBuilder);

            CreatePackageInFakeRemoteRepo(remoteRepoBuilder, "dummy.id", "1.1");

            // Create a dummy sqale file
            string     dummySqaleFilePath = Path.Combine(outputDir, "inputSqale.xml");
            SqaleModel dummySqale         = new SqaleModel();

            Serializer.SaveModel(dummySqale, dummySqaleFilePath);

            ProcessedArgs args = CreateArgs("dummy.id", "1.1", "cs", dummySqaleFilePath, false, false, outputDir);

            // Act
            bool result = apg.Generate(args);

            // Assert
            Assert.IsTrue(result, "Expecting generation to have succeeded");
            AssertSqaleTemplateDoesNotExist(outputDir);
        }
        public void Generate_NoAnalyzersFoundInPackage_GenerateFails()
        {
            // Arrange
            string outputDir = TestUtils.CreateTestDirectory(this.TestContext, ".out");

            TestLogger logger = new TestLogger();

            // Create a fake remote repo containing a package that does not contain analyzers
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);
            remoteRepoBuilder.CreatePackage("no.analyzers.id", "0.9", TestUtils.CreateTextFile("dummy.txt", outputDir), License.NotRequired /* no dependencies */ );

            NuGetPackageHandler nuGetHandler = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, GetLocalNuGetDownloadDir(), logger);
            AnalyzerPluginGenerator apg = new AnalyzerPluginGenerator(nuGetHandler, logger);
            ProcessedArgs args = CreateArgs("no.analyzers.id", "0.9", "cs", null, false, false, outputDir);

            // Act
            bool result = apg.Generate(args);

            // Assert
            Assert.IsFalse(result, "Expecting generation to fail");
            logger.AssertSingleWarningExists(String.Format(UIResources.APG_NoAnalyzersFound, "no.analyzers.id"));
            logger.AssertSingleWarningExists(UIResources.APG_NoAnalyzersInTargetSuggestRecurse);
            logger.AssertWarningsLogged(2);
            AssertSqaleTemplateDoesNotExist(outputDir);
        }
Esempio n. 6
0
        public void Generate_InvalidSqaleFileSpecified_GeneratorError()
        {
            // Arrange
            string outputDir = TestUtils.CreateTestDirectory(this.TestContext, ".out");

            TestLogger logger = new TestLogger();

            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);

            CreatePackageInFakeRemoteRepo(remoteRepoBuilder, "dummy.id", "1.1");

            NuGetPackageHandler nuGetHandler = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, GetLocalNuGetDownloadDir(), logger);

            // Create an invalid sqale file
            string dummySqaleFilePath = Path.Combine(outputDir, "invalidSqale.xml");

            File.WriteAllText(dummySqaleFilePath, "not valid xml");

            AnalyzerPluginGenerator apg = new AnalyzerPluginGenerator(nuGetHandler, logger);

            ProcessedArgs args = CreateArgs("dummy.id", "1.1", "cs", dummySqaleFilePath, false, false, outputDir);

            // Act
            bool result = apg.Generate(args);

            // Assert
            Assert.IsFalse(result, "Expecting generation to have failed");
            AssertSqaleTemplateDoesNotExist(outputDir);
            logger.AssertSingleErrorExists("invalidSqale.xml"); // expecting an error containing the invalid sqale file name
        }
        public void Generate_NoAnalyzersFoundInPackage_GenerateFails()
        {
            // Arrange
            string outputDir = TestUtils.CreateTestDirectory(TestContext, ".out");

            TestLogger logger = new TestLogger();

            // Create a fake remote repo containing a package that does not contain analyzers
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(TestContext);

            remoteRepoBuilder.CreatePackage("no.analyzers.id", "0.9", TestUtils.CreateTextFile("dummy.txt", outputDir), License.NotRequired /* no dependencies */);

            NuGetPackageHandler     nuGetHandler = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, GetLocalNuGetDownloadDir(), logger);
            AnalyzerPluginGenerator apg          = new AnalyzerPluginGenerator(nuGetHandler, logger);
            ProcessedArgs           args         = CreateArgs("no.analyzers.id", "0.9", "cs", false, false, outputDir);

            // Act
            bool result = apg.Generate(args);

            // Assert
            result.Should().BeFalse("Expecting generation to fail");
            logger.AssertSingleWarningExists(String.Format(UIResources.APG_NoAnalyzersFound, "no.analyzers.id"));
            logger.AssertSingleWarningExists(UIResources.APG_NoAnalyzersInTargetSuggestRecurse);
            logger.AssertWarningsLogged(2);
            AssertRuleTemplateDoesNotExist(outputDir);
        }
Esempio n. 8
0
        public void Generate_SqaleFileNotSpecified_TemplateFileCreated()
        {
            // Arrange
            string outputDir = TestUtils.CreateTestDirectory(this.TestContext, ".out");

            TestLogger        logger            = new TestLogger();
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);
            IPackage          child1            = CreatePackageWithAnalyzer(remoteRepoBuilder, "child1.requiredAccept.id", "2.1", License.NotRequired);
            IPackage          child2            = CreatePackageWithAnalyzer(remoteRepoBuilder, "child2.id", "2.2", License.NotRequired);
            IPackage          parent            = CreatePackageWithAnalyzer(remoteRepoBuilder, "parent.id", "1.0", License.NotRequired, child1, child2);

            NuGetPackageHandler nuGetHandler = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, GetLocalNuGetDownloadDir(), logger);

            AnalyzerPluginGenerator apg = new AnalyzerPluginGenerator(nuGetHandler, logger);

            // 1. Generate a plugin for the target package only. Expecting a plugin and a template SQALE file.
            ProcessedArgs args   = CreateArgs("parent.id", "1.0", "cs", null, false, false, outputDir);
            bool          result = apg.Generate(args);

            Assert.IsTrue(result, "Expecting generation to have succeeded");
            AssertSqaleFileExistsForPackage(logger, outputDir, parent);

            // 2. Generate a plugin for target package and all dependencies. Expecting three plugins and associated SQALE files.
            logger.Reset();
            args   = CreateArgs("parent.id", "1.0", "cs", null, false, true /* /recurse = true */, outputDir);
            result = apg.Generate(args);

            Assert.IsTrue(result, "Expecting generation to have succeeded");
            logger.AssertSingleWarningExists(UIResources.APG_RecurseEnabled_SQALENotEnabled);
            AssertSqaleFileExistsForPackage(logger, outputDir, parent);
            AssertSqaleFileExistsForPackage(logger, outputDir, child1);
            AssertSqaleFileExistsForPackage(logger, outputDir, child2);
        }
        public void Generate_LicenseAcceptanceNotRequired_Succeeds()
        {
            // Arrange
            string outputDir = TestUtils.CreateTestDirectory(this.TestContext, ".out");
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);

            // Multi-level dependencies: no package requires license acceptence
            IPackage grandchild = CreatePackageWithAnalyzer(remoteRepoBuilder, "grandchild.id", "1.2", License.NotRequired /* no dependencies */);
            IPackage child = CreatePackageWithAnalyzer(remoteRepoBuilder, "child.id", "1.1", License.NotRequired, grandchild);
            CreatePackageWithAnalyzer(remoteRepoBuilder, "parent.id", "1.0", License.NotRequired, child);

            TestLogger logger = new TestLogger();
            AnalyzerPluginGenerator apg = CreateTestSubjectWithFakeRemoteRepo(remoteRepoBuilder, logger);

            // 1. Acceptance not required -> succeeds if accept = false
            ProcessedArgs args = CreateArgs("parent.id", "1.0", "cs", null, false /* accept licenses */ , outputDir);
            bool result = apg.Generate(args);
            Assert.IsTrue(result, "Generator should succeed if there are no licenses to accept");

            logger.AssertErrorsLogged(0);
            logger.AssertWarningNotLogged("parent.id"); // not expecting warnings about packages that don't require acceptance
            logger.AssertWarningNotLogged("child.id");
            logger.AssertWarningNotLogged("grandchild.id");

            // 2. Acceptance not required -> succeeds if accept = true
            args = CreateArgs("parent.id", "1.0", "cs", null, true /* accept licenses */ , outputDir);
            result = apg.Generate(args);
            Assert.IsTrue(result, "Generator should succeed if there are no licenses to accept");

            logger.AssertErrorsLogged(0);
            logger.AssertWarningNotLogged("parent.id"); // not expecting warnings about packages that don't require acceptance
            logger.AssertWarningNotLogged("child.id");
            logger.AssertWarningNotLogged("grandchild.id");
        }
        public void FetchPackage_VersionSpecified_CorrectVersionSelected()
        {
            string targetNuGetRoot = TestUtils.CreateTestDirectory(this.TestContext, ".nuget.target");

            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);

            BuildAndInstallPackage(remoteRepoBuilder, "package.id.1", "0.8.0");
            BuildAndInstallPackage(remoteRepoBuilder, "package.id.1", "1.0.0-rc1");
            BuildAndInstallPackage(remoteRepoBuilder, "package.id.1", "2.0.0");

            BuildAndInstallPackage(remoteRepoBuilder, "dummy.package.1", "0.8.0");

            BuildAndInstallPackage(remoteRepoBuilder, "package.id.1", "0.9.0");
            BuildAndInstallPackage(remoteRepoBuilder, "package.id.1", "1.0.0");

            NuGetPackageHandler handler = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, targetNuGetRoot, new TestLogger());

            // Check for specific versions
            IPackage actual = handler.FetchPackage("package.id.1", new SemanticVersion("0.8.0"));

            AssertExpectedPackage(actual, "package.id.1", "0.8.0");

            actual = handler.FetchPackage("package.id.1", new SemanticVersion("1.0.0-rc1"));
            AssertExpectedPackage(actual, "package.id.1", "1.0.0-rc1");

            actual = handler.FetchPackage("package.id.1", new SemanticVersion("2.0.0"));
            AssertExpectedPackage(actual, "package.id.1", "2.0.0");
        }
        public void Generate_Recursive_Succeeds()
        {
            // Arrange
            string            outputDir         = TestUtils.CreateTestDirectory(TestContext, ".out");
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(TestContext);

            // Multi-level dependencies: no package requires license acceptence
            IPackage grandchild = CreatePackageWithAnalyzer(remoteRepoBuilder, "grandchild.id", "1.2", License.NotRequired /* no dependencies */);
            IPackage child      = CreatePackageWithAnalyzer(remoteRepoBuilder, "child.id", "1.1", License.NotRequired, grandchild);

            CreatePackageWithAnalyzer(remoteRepoBuilder, "parent.id", "1.0", License.NotRequired, child);

            TestLogger logger           = new TestLogger();
            AnalyzerPluginGenerator apg = CreateTestSubjectWithFakeRemoteRepo(remoteRepoBuilder, logger);

            // Act
            ProcessedArgs args   = CreateArgs("parent.id", "1.0", "cs", false, true /* /recurse = true */, outputDir);
            bool          result = apg.Generate(args);

            // Assert
            result.Should().BeTrue("Generator should succeed if there are no licenses to accept");
            logger.AssertWarningNotLogged("parent.id"); // not expecting warnings about packages that don't require acceptance
            logger.AssertWarningNotLogged("child.id");
            logger.AssertWarningNotLogged("grandchild.id");
            logger.AssertErrorsLogged(0);
            AssertJarsGenerated(outputDir, 3);
        }
        public void Generate_ValidRuleFileSpecified_TemplateFileNotCreated()
        {
            // Arrange
            var outputDir = TestUtils.CreateTestDirectory(this.TestContext, ".out");

            var remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);
            var apg = CreateTestSubjectWithFakeRemoteRepo(remoteRepoBuilder);

            CreatePackageInFakeRemoteRepo(remoteRepoBuilder, "dummy.id", "1.1");

            // Create a dummy rule file
            var dummyRuleFilePath = Path.Combine(outputDir, "inputRule.xml");

            Serializer.SaveModel(new Rules(), dummyRuleFilePath);

            var args = new ProcessedArgsBuilder("dummy.id", outputDir)
                       .SetLanguage("cs")
                       .SetPackageVersion("1.1")
                       .SetRuleFilePath(dummyRuleFilePath)
                       .Build();

            // Act
            bool result = apg.Generate(args);

            // Assert
            result.Should().BeTrue();
            AssertRuleTemplateDoesNotExist(outputDir);
        }
        private IPackageRepository CreateTestPackageWithSingleDependency(string dependentPackageVersion, string testPackageVersion)
        {
            string            dummyTextFile     = CreateDummyContentFile();
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);

            IPackage testPackage = remoteRepoBuilder.CreatePackage(TestPackageId, testPackageVersion, dummyTextFile, RemoteRepoBuilder.License.NotRequired);

            remoteRepoBuilder.CreatePackage(DependentPackageId, dependentPackageVersion, dummyTextFile, RemoteRepoBuilder.License.NotRequired, testPackage);

            return(remoteRepoBuilder.FakeRemoteRepo);
        }
        public void Generate_LicenseAcceptanceNotRequired_NoAnalyzersInTarget()
        {
            // If there are:
            // No required licenses
            // No analyzers in the targeted package, but analyzers in the dependencies
            // We should fail due to the absence of analyzers if we are only generating a plugin for the targeted package
            // We should succeed if we are generating plugins for the targeted package and its dependencies

            // Arrange
            string            outputDir         = TestUtils.CreateTestDirectory(TestContext, ".out");
            string            dummyContentFile  = TestUtils.CreateTextFile("dummy.txt", outputDir, "non-analyzer content file");
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(TestContext);

            // Multi-level dependencies: no package requires license acceptence
            // Parent has no analyzers, but dependencies do
            IPackage grandchild = CreatePackageWithAnalyzer(remoteRepoBuilder, "grandchild.id", "1.2", License.NotRequired /* no dependencies */);
            IPackage child      = CreatePackageWithAnalyzer(remoteRepoBuilder, "child.id", "1.1", License.NotRequired, grandchild);

            remoteRepoBuilder.CreatePackage("parent.id", "1.0", dummyContentFile, License.NotRequired, child);

            TestLogger logger           = new TestLogger();
            AnalyzerPluginGenerator apg = CreateTestSubjectWithFakeRemoteRepo(remoteRepoBuilder, logger);

            // 1. a) Only target package. Acceptance not required -> fails due to absence of analyzers
            ProcessedArgs args = CreateArgs("parent.id", "1.0", "cs", false /* accept licenses */,
                                            false, outputDir);
            bool result = apg.Generate(args);

            result.Should().BeFalse("Expecting generator to fail");

            logger.AssertSingleWarningExists(String.Format(UIResources.APG_NoAnalyzersFound, "parent.id"));
            logger.AssertSingleWarningExists(UIResources.APG_NoAnalyzersInTargetSuggestRecurse);
            logger.AssertWarningsLogged(2);
            logger.AssertErrorsLogged(0);

            // 1. b) Target package and dependencies. Acceptance not required -> succeeds if generate dependencies = true
            logger.Reset();
            args = CreateArgs("parent.id", "1.0", "cs", false /* accept licenses */,
                              true /* generate plugins for dependencies */, outputDir);
            result = apg.Generate(args);
            result.Should().BeTrue("Generator should succeed if there are no licenses to accept");

            logger.AssertSingleWarningExists(String.Format(UIResources.APG_NoAnalyzersFound, "parent.id"));
            logger.AssertWarningNotLogged("child.id");
            logger.AssertWarningNotLogged("grandchild.id");
            logger.AssertWarningsLogged(2);
            logger.AssertErrorsLogged(0);
        }
        public void CreatePluginManifest_FromLocalPackage()
        {
            // We should also be able to create a plugin manifest from an IPackage that is not a DataServicePackage

            // Arrange
            string outputDir = TestUtils.CreateTestDirectory(TestContext, ".out");

            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(TestContext);
            IPackage          testPackage       = remoteRepoBuilder.CreatePackage("Foo.Bar", "1.0.0", TestUtils.CreateTextFile("dummy.txt", outputDir), License.NotRequired);

            // Act
            PluginManifest actualPluginManifest = AnalyzerPluginGenerator.CreatePluginManifest(testPackage);

            // Assert
            actualPluginManifest.Should().NotBeNull();
            actualPluginManifest.License.Should().Be(testPackage.LicenseUrl.ToString());
        }
        public void GetDependencies_DependenciesInstalledLocally_Succeeds()
        {
            // Arrange
            string            targetNuGetRoot   = TestUtils.CreateTestDirectory(this.TestContext, ".nuget.target");
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);
            string            dummyContentFile  = CreateDummyContentFile();

            // Build a dependency graph
            // A depends on B
            // B depends on C, D, E
            // D also depends on E => duplicate dependency
            // E depends on F
            // -> expected [B, C, D, E, F]

            // Leaf nodes
            IPackage f = remoteRepoBuilder.CreatePackage("f", "1.0", dummyContentFile, RemoteRepoBuilder.License.NotRequired /* no dependencies */);
            IPackage c = remoteRepoBuilder.CreatePackage("c", "1.0", dummyContentFile, RemoteRepoBuilder.License.NotRequired /* no dependencies */);

            IPackage e = remoteRepoBuilder.CreatePackage("e", "1.0", dummyContentFile, RemoteRepoBuilder.License.Required, f);
            IPackage d = remoteRepoBuilder.CreatePackage("d", "1.1", dummyContentFile, RemoteRepoBuilder.License.Required, e);

            IPackage b = remoteRepoBuilder.CreatePackage("b", "1.2", dummyContentFile, RemoteRepoBuilder.License.Required, c, d, e);

            IPackage a = remoteRepoBuilder.CreatePackage("a", "2.0", dummyContentFile, RemoteRepoBuilder.License.NotRequired, b);

            NuGetPackageHandler testSubject = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, targetNuGetRoot, new TestLogger());

            // We assume that all of the packages have been installed locally we attempt to resolve the dependencies
            testSubject.FetchPackage("a", new SemanticVersion("2.0"));

            // 1. Package with no dependencies -> empty list
            IEnumerable <IPackage> actualDependencies = testSubject.GetInstalledDependencies(f);

            AssertExpectedPackageIds(actualDependencies /* none */);

            // 2. Package with only direct dependencies -> non-empty list
            actualDependencies = testSubject.GetInstalledDependencies(e);
            AssertExpectedPackageIds(actualDependencies, "f");

            // 3. Package with indirect dependencies -> non-empty list
            actualDependencies = testSubject.GetInstalledDependencies(a);
            AssertExpectedPackageIds(actualDependencies, "b", "c", "d", "e", "f");
        }
        public void Generate_LicenseAcceptanceRequired_ByParentAndDependencies()
        {
            // Arrange
            string            outputDir         = TestUtils.CreateTestDirectory(TestContext, ".out");
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(TestContext);

            // Multi-level: parent and some but not all dependencies require license acceptance
            IPackage grandchild1 = CreatePackageWithAnalyzer(remoteRepoBuilder, "grandchild1.requiredAccept.id", "3.0", License.Required);
            IPackage child1      = CreatePackageWithAnalyzer(remoteRepoBuilder, "child1.requiredAccept.id", "2.1", License.Required);
            IPackage child2      = CreatePackageWithAnalyzer(remoteRepoBuilder, "child2.id", "2.2", License.NotRequired, grandchild1);

            CreatePackageWithAnalyzer(remoteRepoBuilder, "parent.requiredAccept.id", "1.0", License.Required, child1, child2);

            TestLogger logger           = new TestLogger();
            AnalyzerPluginGenerator apg = CreateTestSubjectWithFakeRemoteRepo(remoteRepoBuilder, logger);

            // 1. a) Only target package. User does not accept -> fails with error
            ProcessedArgs args = CreateArgs("parent.requiredAccept.id", "1.0", "cs", false /* accept licenses */,
                                            false, outputDir);
            bool result = apg.Generate(args);

            result.Should().BeFalse("Generator should fail because license has not been accepted");

            logger.AssertSingleErrorExists("parent.requiredAccept.id", "1.0");        // error referring to the main package

            logger.AssertSingleWarningExists("grandchild1.requiredAccept.id", "3.0"); // warning for each licensed package
            logger.AssertSingleWarningExists("child1.requiredAccept.id", "2.1");
            logger.AssertSingleWarningExists("parent.requiredAccept.id", "1.0");

            // 2. User accepts -> succeeds with warnings
            logger.Reset();
            args = CreateArgs("parent.requiredAccept.id", "1.0", "cs", true /* accept licenses */,
                              false, outputDir);
            result = apg.Generate(args);
            result.Should().BeTrue("Generator should succeed if licenses are accepted");

            logger.AssertSingleWarningExists(UIResources.APG_NGAcceptedPackageLicenses); // warning that licenses have been accepted
            logger.AssertSingleWarningExists("grandchild1.requiredAccept.id", "3.0");    // warning for each licensed package
            logger.AssertSingleWarningExists("child1.requiredAccept.id", "2.1");
            logger.AssertSingleWarningExists("parent.requiredAccept.id", "1.0");
            logger.AssertWarningsLogged(4);
        }
        public void FetchPackage_VersionNotSpecified_NoReleaseVersions_LastPreReleaseVersionSelected()
        {
            // Arrange
            string            targetNuGetRoot   = TestUtils.CreateTestDirectory(this.TestContext, ".nuget.target");
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);

            BuildAndInstallPackage(remoteRepoBuilder, "package.id.1", "0.9.0-rc1");
            BuildAndInstallPackage(remoteRepoBuilder, "package.id.1", "1.0.0-rc1");
            BuildAndInstallPackage(remoteRepoBuilder, "package.id.1", "1.1.0-rc1");
            BuildAndInstallPackage(remoteRepoBuilder, "dummy.package.1", "2.0.0");
            BuildAndInstallPackage(remoteRepoBuilder, "dummy.package.1", "2.0.0-rc2");

            NuGetPackageHandler handler = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, targetNuGetRoot, new TestLogger());

            // Act
            IPackage actual = handler.FetchPackage("package.id.1", null);

            // Assert
            AssertExpectedPackage(actual, "package.id.1", "1.1.0-rc1");
        }
        public void FetchPackage_PackageNotFound_NullReturned()
        {
            // Arrange
            string            targetNuGetRoot   = TestUtils.CreateTestDirectory(this.TestContext, ".nuget.target");
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);

            BuildAndInstallPackage(remoteRepoBuilder, "package.id.1", "0.8.0");
            BuildAndInstallPackage(remoteRepoBuilder, "package.id.1", "0.9.0");

            NuGetPackageHandler handler = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, targetNuGetRoot, new TestLogger());

            // 1. Package id not found
            IPackage actual = handler.FetchPackage("unknown.package.id", new SemanticVersion("0.8.0"));

            Assert.IsNull(actual, "Not expecting a package to be found");

            // 2. Package id not found
            actual = handler.FetchPackage("package.id.1", new SemanticVersion("0.7.0"));
            Assert.IsNull(actual, "Not expecting a package to be found");
        }
        public void Generate_RulesFileNotSpecified_TemplateFileCreated()
        {
            // Arrange
            string outputDir = TestUtils.CreateTestDirectory(this.TestContext, ".out");

            var logger            = new TestLogger();
            var remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);
            var child1            = CreatePackageWithAnalyzer(remoteRepoBuilder, "child1.requiredAccept.id", "2.1", License.NotRequired);
            var child2            = CreatePackageWithAnalyzer(remoteRepoBuilder, "child2.id", "2.2", License.NotRequired);
            var parent            = CreatePackageWithAnalyzer(remoteRepoBuilder, "parent.id", "1.0", License.NotRequired, child1, child2);

            var nuGetHandler = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, GetLocalNuGetDownloadDir(), logger);

            var testSubject = new AnalyzerPluginGenerator(nuGetHandler, logger);

            // 1. Generate a plugin for the target package only. Expecting a plugin and a template rule file.
            var args = new ProcessedArgsBuilder("parent.id", outputDir)
                       .SetLanguage("cs")
                       .SetPackageVersion("1.0")
                       .SetRecurseDependencies(true)
                       .Build();
            bool result = testSubject.Generate(args);

            result.Should().BeTrue();

            AssertRuleTemplateFileExistsForPackage(logger, outputDir, parent);

            // 2. Generate a plugin for target package and all dependencies. Expecting three plugins and associated rule files.
            logger.Reset();
            args   = CreateArgs("parent.id", "1.0", "cs", false, true /* /recurse = true */, outputDir);
            result = testSubject.Generate(args);
            result.Should().BeTrue();

            logger.AssertSingleWarningExists(UIResources.APG_RecurseEnabled_RuleCustomizationNotEnabled);
            AssertRuleTemplateFileExistsForPackage(logger, outputDir, parent);
            AssertRuleTemplateFileExistsForPackage(logger, outputDir, child1);
            AssertRuleTemplateFileExistsForPackage(logger, outputDir, child2);
        }
        public void Generate_LicenseAcceptanceRequiredByDependency()
        {
            // Arrange
            string            outputDir         = TestUtils.CreateTestDirectory(TestContext, ".out");
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(TestContext);

            // Parent and child: only child requires license
            IPackage child = CreatePackageWithAnalyzer(remoteRepoBuilder, "child.requiredAccept.id", "2.0", License.Required);

            CreatePackageWithAnalyzer(remoteRepoBuilder, "parent.id", "1.0", License.NotRequired, child);

            TestLogger logger           = new TestLogger();
            AnalyzerPluginGenerator apg = CreateTestSubjectWithFakeRemoteRepo(remoteRepoBuilder, logger);

            // 1. User does not accept -> fails with error
            ProcessedArgs args = CreateArgs("parent.id", "1.0", "cs", false /* accept licenses */,
                                            false, outputDir);
            bool result = apg.Generate(args);

            result.Should().BeFalse("Generator should fail because license has not been accepted");

            logger.AssertSingleErrorExists("parent.id", "1.0");                 // error listing the main package
            logger.AssertSingleWarningExists("child.requiredAccept.id", "2.0"); // warning for each licensed package
            logger.AssertWarningsLogged(1);

            // 2. User accepts -> succeeds with warnings
            logger.Reset();
            args = CreateArgs("parent.id", "1.0", "cs", true /* accept licenses */,
                              false, outputDir);
            result = apg.Generate(args);
            result.Should().BeTrue("Generator should succeed if licenses are accepted");

            logger.AssertSingleWarningExists(UIResources.APG_NGAcceptedPackageLicenses); // warning that licenses have been accepted
            logger.AssertSingleWarningExists("child.requiredAccept.id", "2.0");          // warning for each licensed package
            logger.AssertWarningsLogged(2);
            logger.AssertErrorsLogged(0);
        }
 private static IPackage CreatePackageWithAnalyzer(RemoteRepoBuilder remoteRepoBuilder, string packageId, string packageVersion, License acceptanceRequired, params IPackage[] dependencies)
 {
     return remoteRepoBuilder.CreatePackage(packageId, packageVersion, typeof(RoslynAnalyzer11.CSharpAnalyzer).Assembly.Location, acceptanceRequired, dependencies);
 }
        public void GetDependencies_DependenciesNotInstalledLocally_Warning()
        {
            // Arrange
            string targetNuGetRoot = TestUtils.CreateTestDirectory(this.TestContext, ".nuget.target");
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);
            string dummyContentFile = CreateDummyContentFile();

            IEnumerable<IPackage> actualDependencies;

            // Build a dependency graph: "main" depends on "dependency"
            IPackage dependencyPackage = remoteRepoBuilder.CreatePackage("dependency.package.id", "1.2", dummyContentFile, RemoteRepoBuilder.License.Required /* no dependencies */);
            IPackage mainPackage = remoteRepoBuilder.CreatePackage("a", "2.0", dummyContentFile, RemoteRepoBuilder.License.NotRequired, dependencyPackage);


            // 1. Dependencies have not been installed locally -> warning but no error
            TestLogger logger = new TestLogger();
            NuGetPackageHandler testSubject = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, targetNuGetRoot, logger);
            actualDependencies = testSubject.GetInstalledDependencies(mainPackage);
            AssertExpectedPackageIds(actualDependencies /* no dependencies resolved*/);

            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(1);
            logger.AssertSingleWarningExists("dependency.package.id");


            // 2. Now install the package -> dependencies should resolve ok
            logger = new TestLogger();
            testSubject = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, targetNuGetRoot, logger);

            testSubject.FetchPackage(mainPackage.Id, mainPackage.Version);
            actualDependencies = testSubject.GetInstalledDependencies(mainPackage);
            AssertExpectedPackageIds(actualDependencies, "dependency.package.id");

            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(0);
        }
 private AnalyzerPluginGenerator CreateTestSubjectWithFakeRemoteRepo(RemoteRepoBuilder remoteRepoBuilder)
 {
     return CreateTestSubjectWithFakeRemoteRepo(remoteRepoBuilder, new TestLogger());
 }
        public void Generate_InvalidSqaleFileSpecified_GeneratorError()
        {
            // Arrange
            string outputDir = TestUtils.CreateTestDirectory(this.TestContext, ".out");

            TestLogger logger = new TestLogger();

            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);
            CreatePackageInFakeRemoteRepo(remoteRepoBuilder, "dummy.id", "1.1");

            NuGetPackageHandler nuGetHandler = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, GetLocalNuGetDownloadDir(), logger);

            // Create an invalid sqale file
            string dummySqaleFilePath = Path.Combine(outputDir, "invalidSqale.xml");
            File.WriteAllText(dummySqaleFilePath, "not valid xml");

            AnalyzerPluginGenerator apg = new AnalyzerPluginGenerator(nuGetHandler, logger);

            ProcessedArgs args = CreateArgs("dummy.id", "1.1", "cs", dummySqaleFilePath, false, outputDir);

            // Act
            bool result = apg.Generate(args);

            // Assert
            Assert.IsFalse(result, "Expecting generation to have failed");
            AssertSqaleTemplateDoesNotExist(outputDir);
            logger.AssertSingleErrorExists("invalidSqale.xml"); // expecting an error containing the invalid sqale file name
        }
        public void Generate_SqaleFileNotSpecified_TemplateFileCreated()
        {
            // Arrange
            string outputDir = TestUtils.CreateTestDirectory(this.TestContext, ".out");

            TestLogger logger = new TestLogger();

            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);
            CreatePackageInFakeRemoteRepo(remoteRepoBuilder, "dummy.id", "1.1");

            NuGetPackageHandler nuGetHandler = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, GetLocalNuGetDownloadDir(), logger);

            string expectedTemplateSqaleFilePath = Path.Combine(outputDir, "dummy.id.1.1.sqale.template.xml");

            AnalyzerPluginGenerator apg = new AnalyzerPluginGenerator(nuGetHandler, logger);

            ProcessedArgs args = CreateArgs("dummy.id", "1.1", "cs", null, false, outputDir);

            // Act
            bool result = apg.Generate(args);

            // Assert
            Assert.IsTrue(result, "Expecting generation to have succeeded");
            Assert.IsTrue(File.Exists(expectedTemplateSqaleFilePath), "Expecting a template sqale file to have been created");
            this.TestContext.AddResultFile(expectedTemplateSqaleFilePath);
            logger.AssertSingleInfoMessageExists(expectedTemplateSqaleFilePath); // should be a message about the generated file
        }
        public void Generate_LicenseAcceptanceRequired_ByParentAndDependencies()
        {
            // Arrange
            string outputDir = TestUtils.CreateTestDirectory(this.TestContext, ".out");
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);

            // Multi-level: parent and some but not all dependencies require license acceptance
            IPackage grandchild1 = CreatePackageWithAnalyzer(remoteRepoBuilder, "grandchild1.requiredAccept.id", "3.0", License.Required);
            IPackage child1 = CreatePackageWithAnalyzer(remoteRepoBuilder, "child1.requiredAccept.id", "2.1", License.Required);
            IPackage child2 = CreatePackageWithAnalyzer(remoteRepoBuilder, "child2.id", "2.2", License.NotRequired, grandchild1);
            CreatePackageWithAnalyzer(remoteRepoBuilder, "parent.requiredAccept.id", "1.0", License.Required, child1, child2);

            TestLogger logger = new TestLogger();
            AnalyzerPluginGenerator apg = CreateTestSubjectWithFakeRemoteRepo(remoteRepoBuilder, logger);

            // 1. User does not accept -> fails with error
            ProcessedArgs args = CreateArgs("parent.requiredAccept.id", "1.0", "cs", null, false /* accept licenses */ , outputDir);
            bool result = apg.Generate(args);
            Assert.IsFalse(result, "Generator should fail because license has not been accepted");

            logger.AssertSingleErrorExists("parent.requiredAccept.id", "1.0"); // error referring to the main package

            logger.AssertSingleWarningExists("grandchild1.requiredAccept.id", "3.0"); // warning for each licensed package
            logger.AssertSingleWarningExists("child1.requiredAccept.id", "2.1");
            logger.AssertSingleWarningExists("parent.requiredAccept.id", "1.0");

            // 2. User accepts -> succeeds with warnings
            logger.Reset();
            args = CreateArgs("parent.requiredAccept.id", "1.0", "cs", null, true /* accept licenses */ , outputDir);
            result = apg.Generate(args);
            Assert.IsTrue(result, "Generator should succeed if licenses are accepted");

            logger.AssertSingleWarningExists(UIResources.APG_NGAcceptedPackageLicenses); // warning that licenses have been accepted
            logger.AssertSingleWarningExists("grandchild1.requiredAccept.id", "3.0"); // warning for each licensed package
            logger.AssertSingleWarningExists("child1.requiredAccept.id", "2.1");
            logger.AssertSingleWarningExists("parent.requiredAccept.id", "1.0");
            logger.AssertWarningsLogged(4);
        }
        private IPackage BuildAndInstallPackage(RemoteRepoBuilder remoteRepoBuilder, string id, string version)
        {
            string dummyTextFile = CreateDummyContentFile();

            return(remoteRepoBuilder.CreatePackage(id, version, dummyTextFile, RemoteRepoBuilder.License.NotRequired));
        }
        private IPackageRepository CreateTestPackageWithSingleDependency(string dependentPackageVersion, string testPackageVersion)
        {
            string dummyTextFile = CreateDummyContentFile();
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);

            IPackage testPackage = remoteRepoBuilder.CreatePackage(TestPackageId, testPackageVersion, dummyTextFile, RemoteRepoBuilder.License.NotRequired);
            remoteRepoBuilder.CreatePackage(DependentPackageId, dependentPackageVersion, dummyTextFile, RemoteRepoBuilder.License.NotRequired, testPackage);

            return remoteRepoBuilder.FakeRemoteRepo;
        }
        public void Generate_LicenseAcceptanceRequired_NoAnalysersInTarget()
        {
            // If there are:
            // Required licenses
            // No analyzers in the targeted package, but analyzers in the dependencies
            // We should fail due to the absence of analyzers if we are only generating a plugin for the targeted package
            // We should fail with an error due to licenses if we are generating plugins for the targeted package and dependencies

            // Arrange
            string outputDir        = TestUtils.CreateTestDirectory(TestContext, ".out");
            string dummyContentFile = TestUtils.CreateTextFile("dummy.txt", outputDir, "non-analyzer content file");

            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(TestContext);

            // Multi-level: parent and some but not all dependencies require license acceptance
            // Parent has no analyzers, but dependencies do
            IPackage child1 = CreatePackageWithAnalyzer(remoteRepoBuilder, "child1.requiredAccept.id", "2.1", License.Required);
            IPackage child2 = CreatePackageWithAnalyzer(remoteRepoBuilder, "child2.id", "2.2", License.NotRequired);

            remoteRepoBuilder.CreatePackage("non-analyzer.parent.requireAccept.id", "1.0", dummyContentFile, License.Required, child1, child2);

            TestLogger logger           = new TestLogger();
            AnalyzerPluginGenerator apg = CreateTestSubjectWithFakeRemoteRepo(remoteRepoBuilder, logger);

            // 1. a) Only target package. User does not accept, but no analyzers so no license prompt -> fails due to absence of analyzers
            ProcessedArgs args = CreateArgs("non-analyzer.parent.requireAccept.id", "1.0", "cs", false /* accept licenses */,
                                            false, outputDir);
            bool result = apg.Generate(args);

            result.Should().BeFalse("Expecting generator to fail");

            logger.AssertSingleWarningExists(String.Format(UIResources.APG_NoAnalyzersFound, "non-analyzer.parent.requireAccept.id"));
            logger.AssertSingleWarningExists(UIResources.APG_NoAnalyzersInTargetSuggestRecurse);
            logger.AssertWarningsLogged(2);
            logger.AssertErrorsLogged(0);

            // 1. b) Target package and dependencies. User does not accept.
            // No analyzers in the target package, but analyzers in the dependencies -> fails with error
            logger.Reset();
            args = CreateArgs("non-analyzer.parent.requireAccept.id", "1.0", "cs", false /* accept licenses */,
                              true /* generate plugins for dependencies */, outputDir);
            result = apg.Generate(args);
            result.Should().BeFalse("Generator should fail because license has not been accepted");

            logger.AssertSingleWarningExists(String.Format(UIResources.APG_NoAnalyzersFound, "non-analyzer.parent.requireAccept.id"));
            logger.AssertSingleWarningExists("non-analyzer.parent.requireAccept.id", "1.0"); // warning for each licensed package
            logger.AssertSingleWarningExists(child1.Id, child1.Version.ToString());
            logger.AssertWarningsLogged(3);
            logger.AssertSingleErrorExists("non-analyzer.parent.requireAccept.id", "1.0"); // error listing the main package
            logger.AssertErrorsLogged(1);

            // 2. b) Target package and dependencies. User accepts.
            // No analyzers in the target package, but analyzers in the dependencies -> succeeds with warnings
            logger.Reset();
            args = CreateArgs("non-analyzer.parent.requireAccept.id", "1.0", "cs", true /* accept licenses */,
                              true /* generate plugins for dependencies */, outputDir);
            result = apg.Generate(args);
            result.Should().BeTrue("Generator should succeed if licenses are accepted");

            logger.AssertSingleWarningExists(String.Format(UIResources.APG_NoAnalyzersFound, "non-analyzer.parent.requireAccept.id"));
            logger.AssertSingleWarningExists(UIResources.APG_NGAcceptedPackageLicenses);     // warning that licenses have been accepted
            logger.AssertSingleWarningExists("non-analyzer.parent.requireAccept.id", "1.0"); // warning for each licensed package
            logger.AssertSingleWarningExists(child1.Id, child1.Version.ToString());
            logger.AssertWarningsLogged(5);
            logger.AssertErrorsLogged(0);
        }
        public void Generate_LicenseAcceptanceNotRequired_NoAnalyzersInTarget()
        {
            // If there are:
            // No required licenses
            // No analyzers in the targeted package, but analyzers in the dependencies
            // We should fail due to the absence of analyzers if we are only generating a plugin for the targeted package
            // We should succeed if we are generating plugins for the targeted package and its dependencies

            // Arrange
            string outputDir = TestUtils.CreateTestDirectory(this.TestContext, ".out");
            string dummyContentFile = TestUtils.CreateTextFile("dummy.txt", outputDir, "non-analyzer content file");
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);

            // Multi-level dependencies: no package requires license acceptence
            // Parent has no analyzers, but dependencies do
            IPackage grandchild = CreatePackageWithAnalyzer(remoteRepoBuilder, "grandchild.id", "1.2", License.NotRequired /* no dependencies */);
            IPackage child = CreatePackageWithAnalyzer(remoteRepoBuilder, "child.id", "1.1", License.NotRequired, grandchild);
            remoteRepoBuilder.CreatePackage("parent.id", "1.0", dummyContentFile, License.NotRequired, child);

            TestLogger logger = new TestLogger();
            AnalyzerPluginGenerator apg = CreateTestSubjectWithFakeRemoteRepo(remoteRepoBuilder, logger);

            // 1. a) Only target package. Acceptance not required -> fails due to absence of analyzers
            ProcessedArgs args = CreateArgs("parent.id", "1.0", "cs", null, false /* accept licenses */ ,
                false, outputDir);
            bool result = apg.Generate(args);
            Assert.IsFalse(result, "Expecting generator to fail");

            logger.AssertSingleWarningExists(String.Format(UIResources.APG_NoAnalyzersFound, "parent.id"));
            logger.AssertSingleWarningExists(UIResources.APG_NoAnalyzersInTargetSuggestRecurse);
            logger.AssertWarningsLogged(2);
            logger.AssertErrorsLogged(0);

            // 1. b) Target package and dependencies. Acceptance not required -> succeeds if generate dependencies = true
            logger.Reset();
            args = CreateArgs("parent.id", "1.0", "cs", null, false /* accept licenses */ ,
                true /* generate plugins for dependencies */, outputDir);
            result = apg.Generate(args);
            Assert.IsTrue(result, "Generator should succeed if there are no licenses to accept");

            logger.AssertSingleWarningExists(String.Format(UIResources.APG_NoAnalyzersFound, "parent.id"));
            logger.AssertWarningNotLogged("child.id");
            logger.AssertWarningNotLogged("grandchild.id");
            logger.AssertWarningsLogged(2);
            logger.AssertErrorsLogged(0);
        }
        public void Generate_LicenseAcceptanceRequired_NoAnalysersInTarget()
        {
            // If there are:
            // Required licenses
            // No analyzers in the targeted package, but analyzers in the dependencies
            // We should fail due to the absence of analyzers if we are only generating a plugin for the targeted package
            // We should fail with an error due to licenses if we are generating plugins for the targeted package and dependencies

            // Arrange
            string outputDir = TestUtils.CreateTestDirectory(this.TestContext, ".out");
            string dummyContentFile = TestUtils.CreateTextFile("dummy.txt", outputDir, "non-analyzer content file");

            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);

            // Multi-level: parent and some but not all dependencies require license acceptance
            // Parent has no analyzers, but dependencies do
            IPackage child1 = CreatePackageWithAnalyzer(remoteRepoBuilder, "child1.requiredAccept.id", "2.1", License.Required);
            IPackage child2 = CreatePackageWithAnalyzer(remoteRepoBuilder, "child2.id", "2.2", License.NotRequired);
            remoteRepoBuilder.CreatePackage("non-analyzer.parent.requireAccept.id", "1.0", dummyContentFile, License.Required, child1, child2);

            TestLogger logger = new TestLogger();
            AnalyzerPluginGenerator apg = CreateTestSubjectWithFakeRemoteRepo(remoteRepoBuilder, logger);

            // 1. a) Only target package. User does not accept, but no analyzers so no license prompt -> fails due to absence of analyzers
            ProcessedArgs args = CreateArgs("non-analyzer.parent.requireAccept.id", "1.0", "cs", null, false /* accept licenses */ ,
                false, outputDir);
            bool result = apg.Generate(args);
            Assert.IsFalse(result, "Expecting generator to fail");

            logger.AssertSingleWarningExists(String.Format(UIResources.APG_NoAnalyzersFound, "non-analyzer.parent.requireAccept.id"));
            logger.AssertSingleWarningExists(UIResources.APG_NoAnalyzersInTargetSuggestRecurse);
            logger.AssertWarningsLogged(2);
            logger.AssertErrorsLogged(0);

            // 1. b) Target package and dependencies. User does not accept.
            // No analyzers in the target package, but analyzers in the dependencies -> fails with error
            logger.Reset();
            args = CreateArgs("non-analyzer.parent.requireAccept.id", "1.0", "cs", null, false /* accept licenses */ ,
                true /* generate plugins for dependencies */, outputDir);
            result = apg.Generate(args);
            Assert.IsFalse(result, "Generator should fail because license has not been accepted");

            logger.AssertSingleWarningExists(String.Format(UIResources.APG_NoAnalyzersFound, "non-analyzer.parent.requireAccept.id"));
            logger.AssertSingleWarningExists("non-analyzer.parent.requireAccept.id", "1.0"); // warning for each licensed package
            logger.AssertSingleWarningExists(child1.Id, child1.Version.ToString());
            logger.AssertWarningsLogged(3);
            logger.AssertSingleErrorExists("non-analyzer.parent.requireAccept.id", "1.0"); // error listing the main package
            logger.AssertErrorsLogged(1);

            // 2. b) Target package and dependencies. User accepts.
            // No analyzers in the target package, but analyzers in the dependencies -> succeeds with warnings
            logger.Reset();
            args = CreateArgs("non-analyzer.parent.requireAccept.id", "1.0", "cs", null, true /* accept licenses */ ,
                true /* generate plugins for dependencies */, outputDir);
            result = apg.Generate(args);
            Assert.IsTrue(result, "Generator should succeed if licenses are accepted");

            logger.AssertSingleWarningExists(String.Format(UIResources.APG_NoAnalyzersFound, "non-analyzer.parent.requireAccept.id"));
            logger.AssertSingleWarningExists(UIResources.APG_NGAcceptedPackageLicenses); // warning that licenses have been accepted
            logger.AssertSingleWarningExists("non-analyzer.parent.requireAccept.id", "1.0"); // warning for each licensed package
            logger.AssertSingleWarningExists(child1.Id, child1.Version.ToString());
            logger.AssertWarningsLogged(5);
            logger.AssertErrorsLogged(0);
        }
 private IPackage BuildAndInstallPackage(RemoteRepoBuilder remoteRepoBuilder, string id, string version)
 {
     string dummyTextFile = CreateDummyContentFile();
     return remoteRepoBuilder.CreatePackage(id, version, dummyTextFile, RemoteRepoBuilder.License.NotRequired);
 }
        public void FetchPackage_PackageNotFound_NullReturned()
        {
            // Arrange
            string targetNuGetRoot = TestUtils.CreateTestDirectory(this.TestContext, ".nuget.target");
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);

            BuildAndInstallPackage(remoteRepoBuilder, "package.id.1", "0.8.0");
            BuildAndInstallPackage(remoteRepoBuilder, "package.id.1", "0.9.0");

            NuGetPackageHandler handler = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, targetNuGetRoot, new TestLogger());

            // 1. Package id not found
            IPackage actual = handler.FetchPackage("unknown.package.id", new SemanticVersion("0.8.0"));
            Assert.IsNull(actual, "Not expecting a package to be found");

            // 2. Package id not found
            actual = handler.FetchPackage("package.id.1", new SemanticVersion("0.7.0"));
            Assert.IsNull(actual, "Not expecting a package to be found");
        }
        public void GetDependencies_DependenciesInstalledLocally_Succeeds()
        {
            // Arrange
            string targetNuGetRoot = TestUtils.CreateTestDirectory(this.TestContext, ".nuget.target");
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);
            string dummyContentFile = CreateDummyContentFile();

            // Build a dependency graph 
            // A depends on B
            // B depends on C, D, E
            // D also depends on E => duplicate dependency
            // E depends on F
            // -> expected [B, C, D, E, F]
            
            // Leaf nodes
            IPackage f = remoteRepoBuilder.CreatePackage("f", "1.0", dummyContentFile, RemoteRepoBuilder.License.NotRequired /* no dependencies */);
            IPackage c = remoteRepoBuilder.CreatePackage("c", "1.0", dummyContentFile, RemoteRepoBuilder.License.NotRequired /* no dependencies */);

            IPackage e = remoteRepoBuilder.CreatePackage("e", "1.0", dummyContentFile, RemoteRepoBuilder.License.Required, f);
            IPackage d = remoteRepoBuilder.CreatePackage("d", "1.1", dummyContentFile, RemoteRepoBuilder.License.Required, e);

            IPackage b = remoteRepoBuilder.CreatePackage("b", "1.2", dummyContentFile, RemoteRepoBuilder.License.Required, c, d, e);

            IPackage a = remoteRepoBuilder.CreatePackage("a", "2.0", dummyContentFile, RemoteRepoBuilder.License.NotRequired, b);

            NuGetPackageHandler testSubject = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, targetNuGetRoot, new TestLogger());

            // We assume that all of the packages have been installed locally we attempt to resolve the dependencies
            testSubject.FetchPackage("a", new SemanticVersion("2.0"));

            // 1. Package with no dependencies -> empty list
            IEnumerable<IPackage> actualDependencies = testSubject.GetInstalledDependencies(f);
            AssertExpectedPackageIds(actualDependencies /* none */);

            // 2. Package with only direct dependencies -> non-empty list
            actualDependencies = testSubject.GetInstalledDependencies(e);
            AssertExpectedPackageIds(actualDependencies, "f");

            // 3. Package with indirect dependencies -> non-empty list
            actualDependencies = testSubject.GetInstalledDependencies(a);
            AssertExpectedPackageIds(actualDependencies, "b", "c", "d", "e", "f");
        }
 private AnalyzerPluginGenerator CreateTestSubjectWithFakeRemoteRepo(RemoteRepoBuilder remoteRepoBuilder)
 {
     return(CreateTestSubjectWithFakeRemoteRepo(remoteRepoBuilder, new TestLogger()));
 }
        public void Generate_LicenseAcceptanceNotRequestedIfNoAnalysers()
        {
            // No point in asking the user to accept licenses for packages that don't contain analyzers

            // Arrange
            string outputDir = TestUtils.CreateTestDirectory(this.TestContext, ".out");
            string dummyContentFile = TestUtils.CreateTextFile("dummy.txt", outputDir, "non-analyzer content file");

            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);

            // Parent only: requires license
            remoteRepoBuilder.CreatePackage("non.analyzer.requireAccept.id", "1.0", dummyContentFile, License.Required);

            TestLogger logger = new TestLogger();
            AnalyzerPluginGenerator apg = CreateTestSubjectWithFakeRemoteRepo(remoteRepoBuilder, logger);

            // 1. User does not accept, but no analyzers so no license prompt -> fails due absence of analyzers
            ProcessedArgs args = CreateArgs("non.analyzer.requireAccept.id", "1.0", "cs", null, false /* accept licenses */ , outputDir);
            bool result = apg.Generate(args);
            Assert.IsFalse(result, "Expecting generator to fail");

            logger.AssertSingleWarningExists(UIResources.APG_NoAnalyzersFound);
            logger.AssertWarningsLogged(1);
            logger.AssertErrorsLogged(0);
        }
        private AnalyzerPluginGenerator CreateTestSubjectWithFakeRemoteRepo(RemoteRepoBuilder remoteRepoBuilder, TestLogger logger)
        {
            NuGetPackageHandler nuGetHandler = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, GetLocalNuGetDownloadDir(), logger);

            return(new AnalyzerPluginGenerator(nuGetHandler, logger));
        }
        public void Generate_ValidSqaleFileSpecified_TemplateFileNotCreated()
        {
            // Arrange
            string outputDir = TestUtils.CreateTestDirectory(this.TestContext, ".out");

            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);
            AnalyzerPluginGenerator apg = CreateTestSubjectWithFakeRemoteRepo(remoteRepoBuilder);

            CreatePackageInFakeRemoteRepo(remoteRepoBuilder, "dummy.id", "1.1");

            // Create a dummy sqale file
            string dummySqaleFilePath = Path.Combine(outputDir, "inputSqale.xml");
            SqaleModel dummySqale = new SqaleModel();
            Serializer.SaveModel(dummySqale, dummySqaleFilePath);

            ProcessedArgs args = CreateArgs("dummy.id", "1.1", "cs", dummySqaleFilePath, false, outputDir);

            // Act
            bool result = apg.Generate(args);

            // Assert
            Assert.IsTrue(result, "Expecting generation to have succeeded");
            AssertSqaleTemplateDoesNotExist(outputDir);
        }
 private static IPackage CreatePackageWithAnalyzer(RemoteRepoBuilder remoteRepoBuilder, string packageId, string packageVersion, License acceptanceRequired, params IPackage[] dependencies)
 {
     return(remoteRepoBuilder.CreatePackage(packageId, packageVersion, typeof(RoslynAnalyzer34.CSharpAnalyzer).Assembly.Location, acceptanceRequired, dependencies));
 }
        public void CreatePluginManifest_FromLocalPackage()
        {
            // We should also be able to create a plugin manifest from an IPackage that is not a DataServicePackage

            // Arrange
            string outputDir = TestUtils.CreateTestDirectory(this.TestContext, ".out");

            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);
            IPackage testPackage = remoteRepoBuilder.CreatePackage("Foo.Bar", "1.0.0", TestUtils.CreateTextFile("dummy.txt", outputDir), License.NotRequired);

            // Act
            PluginManifest actualPluginManifest = AnalyzerPluginGenerator.CreatePluginManifest(testPackage);

            // Assert
            Assert.IsNotNull(actualPluginManifest);
            Assert.AreEqual(testPackage.LicenseUrl.ToString(), actualPluginManifest.License, false);
        }
 private void CreatePackageInFakeRemoteRepo(RemoteRepoBuilder remoteRepoBuilder, string packageId, string packageVersion)
 {
     remoteRepoBuilder.CreatePackage(packageId, packageVersion, typeof(RoslynAnalyzer34.AbstractAnalyzer).Assembly.Location, License.NotRequired /* no dependencies */);
 }
 private AnalyzerPluginGenerator CreateTestSubjectWithFakeRemoteRepo(RemoteRepoBuilder remoteRepoBuilder, TestLogger logger)
 {
     NuGetPackageHandler nuGetHandler = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, GetLocalNuGetDownloadDir(), logger);
     return new AnalyzerPluginGenerator(nuGetHandler, logger);
 }
        public void Generate_SqaleFileNotSpecified_TemplateFileCreated()
        {
            // Arrange
            string outputDir = TestUtils.CreateTestDirectory(this.TestContext, ".out");

            TestLogger logger = new TestLogger();
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);
            IPackage child1 = CreatePackageWithAnalyzer(remoteRepoBuilder, "child1.requiredAccept.id", "2.1", License.NotRequired);
            IPackage child2 = CreatePackageWithAnalyzer(remoteRepoBuilder, "child2.id", "2.2", License.NotRequired);
            IPackage parent = CreatePackageWithAnalyzer(remoteRepoBuilder, "parent.id", "1.0", License.NotRequired, child1, child2);

            NuGetPackageHandler nuGetHandler = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, GetLocalNuGetDownloadDir(), logger);
            
            AnalyzerPluginGenerator apg = new AnalyzerPluginGenerator(nuGetHandler, logger);

            // 1. Generate a plugin for the target package only. Expecting a plugin and a template SQALE file.
            ProcessedArgs args = CreateArgs("parent.id", "1.0", "cs", null, false, false, outputDir);
            bool result = apg.Generate(args);

            Assert.IsTrue(result, "Expecting generation to have succeeded");
            AssertSqaleFileExistsForPackage(logger, outputDir, parent);

            // 2. Generate a plugin for target package and all dependencies. Expecting three plugins and associated SQALE files.
            logger.Reset();
            args = CreateArgs("parent.id", "1.0", "cs", null, false, true /* /recurse = true */, outputDir);
            result = apg.Generate(args);

            Assert.IsTrue(result, "Expecting generation to have succeeded");
            logger.AssertSingleWarningExists(UIResources.APG_RecurseEnabled_SQALENotEnabled);
            AssertSqaleFileExistsForPackage(logger, outputDir, parent);
            AssertSqaleFileExistsForPackage(logger, outputDir, child1);
            AssertSqaleFileExistsForPackage(logger, outputDir, child2);

        }
 private void CreatePackageInFakeRemoteRepo(RemoteRepoBuilder remoteRepoBuilder, string packageId, string packageVersion)
 {
     remoteRepoBuilder.CreatePackage(packageId, packageVersion, typeof(RoslynAnalyzer11.AbstractAnalyzer).Assembly.Location, License.NotRequired /* no dependencies */ );
 }
        public void FetchPackage_VersionSpecified_CorrectVersionSelected()
        {
            string targetNuGetRoot = TestUtils.CreateTestDirectory(this.TestContext, ".nuget.target");

            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);
            BuildAndInstallPackage(remoteRepoBuilder, "package.id.1", "0.8.0");
            BuildAndInstallPackage(remoteRepoBuilder, "package.id.1", "1.0.0-rc1");
            BuildAndInstallPackage(remoteRepoBuilder, "package.id.1", "2.0.0");

            BuildAndInstallPackage(remoteRepoBuilder, "dummy.package.1", "0.8.0");

            BuildAndInstallPackage(remoteRepoBuilder, "package.id.1", "0.9.0");
            BuildAndInstallPackage(remoteRepoBuilder, "package.id.1", "1.0.0");

            NuGetPackageHandler handler = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, targetNuGetRoot, new TestLogger());

            // Check for specific versions
            IPackage actual = handler.FetchPackage("package.id.1", new SemanticVersion("0.8.0"));
            AssertExpectedPackage(actual, "package.id.1", "0.8.0");

            actual = handler.FetchPackage("package.id.1", new SemanticVersion("1.0.0-rc1"));
            AssertExpectedPackage(actual, "package.id.1", "1.0.0-rc1");

            actual = handler.FetchPackage("package.id.1", new SemanticVersion("2.0.0"));
            AssertExpectedPackage(actual, "package.id.1", "2.0.0");
        }
        public void Generate_LicenseAcceptanceRequiredByMainPackage()
        {
            // Arrange
            string outputDir = TestUtils.CreateTestDirectory(this.TestContext, ".out");
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);

            // Parent and child: only parent requires license
            IPackage child = CreatePackageWithAnalyzer(remoteRepoBuilder, "child.id", "1.1", License.NotRequired);
            CreatePackageWithAnalyzer(remoteRepoBuilder, "parent.requiredAccept.id", "1.0", License.Required, child);

            TestLogger logger = new TestLogger();
            AnalyzerPluginGenerator apg = CreateTestSubjectWithFakeRemoteRepo(remoteRepoBuilder, logger);

            // 1. User does not accept -> fails with error
            ProcessedArgs args = CreateArgs("parent.requiredAccept.id", "1.0", "cs", null, false /* accept licenses */ , outputDir);
            bool result = apg.Generate(args);
            Assert.IsFalse(result, "Generator should fail because license has not been accepted");

            logger.AssertSingleErrorExists("parent.requiredAccept.id", "1.0"); // error listing the main package
            logger.AssertSingleWarningExists("parent.requiredAccept.id", "1.0"); // warning for each licensed package
            logger.AssertWarningsLogged(1);

            // 2. User accepts -> succeeds with warnings
            logger.Reset();
            args = CreateArgs("parent.requiredAccept.id", "1.0", "cs", null, true /* accept licenses */ , outputDir);
            result = apg.Generate(args);
            Assert.IsTrue(result, "Generator should succeed if licenses are accepted");

            logger.AssertSingleWarningExists(UIResources.APG_NGAcceptedPackageLicenses); // warning that licenses accepted
            logger.AssertSingleWarningExists("parent.requiredAccept.id", "1.0"); // warning for each licensed package
            logger.AssertWarningsLogged(2);
            logger.AssertErrorsLogged(0);
        }
        public void FetchPackage_VersionNotSpecified_NoReleaseVersions_LastPreReleaseVersionSelected()
        {
            // Arrange
            string targetNuGetRoot = TestUtils.CreateTestDirectory(this.TestContext, ".nuget.target");
            RemoteRepoBuilder remoteRepoBuilder = new RemoteRepoBuilder(this.TestContext);

            BuildAndInstallPackage(remoteRepoBuilder, "package.id.1", "0.9.0-rc1");
            BuildAndInstallPackage(remoteRepoBuilder, "package.id.1", "1.0.0-rc1");
            BuildAndInstallPackage(remoteRepoBuilder, "package.id.1", "1.1.0-rc1");
            BuildAndInstallPackage(remoteRepoBuilder, "dummy.package.1", "2.0.0");
            BuildAndInstallPackage(remoteRepoBuilder, "dummy.package.1", "2.0.0-rc2");

            NuGetPackageHandler handler = new NuGetPackageHandler(remoteRepoBuilder.FakeRemoteRepo, targetNuGetRoot, new TestLogger());

            // Act
            IPackage actual = handler.FetchPackage("package.id.1", null);

            // Assert
            AssertExpectedPackage(actual, "package.id.1", "1.1.0-rc1");
        }