public void EmbeddedInstall_CachingScenarios()
        {
            // Arrange
            var localCacheDir = TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext);
            var logger        = new TestLogger();

            var requestA = new Plugin("p111", "1.0-SNAPSHOT", "p1.zip");
            var requestB = new Plugin("p222", "9.1.3.0", "p2.zip");

            var mockServer = new MockSonarQubeServer();

            AddPlugin(mockServer, requestA, "aaa", "bbb");
            AddPlugin(mockServer, requestB, "ccc");

            var expectedPlugin111Paths = CalculateExpectedCachedFilePaths(localCacheDir, 0, "aaa", "bbb");
            var expectedPlugin222Paths = CalculateExpectedCachedFilePaths(localCacheDir, 1, "ccc");
            var allExpectedPaths       = new List <string>(expectedPlugin111Paths);

            allExpectedPaths.AddRange(expectedPlugin222Paths);

            var testSubject = new EmbeddedAnalyzerInstaller(mockServer, localCacheDir, logger);

            AssertExpectedFilesInCache(0, localCacheDir); // cache should be empty to start with

            // 1. Empty cache -> cache miss -> server called
            var actualFiles = testSubject.InstallAssemblies(new Plugin[] { requestA });

            mockServer.AssertMethodCalled(DownloadEmbeddedFileMethodName, 1); // should have tried to download

            AssertExpectedFilesReturned(expectedPlugin111Paths, actualFiles);
            AssertExpectedFilesExist(expectedPlugin111Paths);
            AssertExpectedFilesInCache(4, localCacheDir); // only files for the first request should exist

            // 2. New request + request -> partial cache miss -> server called only for the new request
            actualFiles = testSubject.InstallAssemblies(new Plugin[] { requestA, requestB });
            mockServer.AssertMethodCalled(DownloadEmbeddedFileMethodName, 2); // new request

            AssertExpectedFilesReturned(allExpectedPaths, actualFiles);
            AssertExpectedFilesExist(allExpectedPaths);
            AssertExpectedFilesInCache(6, localCacheDir); // files for both plugins should exist

            // 3. Repeat the request -> cache hit -> server not called
            actualFiles = testSubject.InstallAssemblies(new Plugin[] { requestA, requestB });
            mockServer.AssertMethodCalled(DownloadEmbeddedFileMethodName, 2); // call count should not have changed

            AssertExpectedFilesReturned(allExpectedPaths, actualFiles);

            // 4. Clear the cache and request both -> cache miss -> multiple requests
            Directory.Delete(localCacheDir, true);
            Directory.Exists(localCacheDir).Should().BeFalse("Test error: failed to delete the local cache directory");

            actualFiles = testSubject.InstallAssemblies(new Plugin[] { requestA, requestB });
            mockServer.AssertMethodCalled(DownloadEmbeddedFileMethodName, 4); // two new requests

            AssertExpectedFilesReturned(allExpectedPaths, actualFiles);
            AssertExpectedFilesExist(allExpectedPaths);
            AssertExpectedFilesInCache(6, localCacheDir); // files for both plugins should exist
        }
        public void PreProc_NoPlugin()
        {
            // Arrange
            var workingDir = TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext);
            var logger     = new TestLogger();

            // Configure the server
            var mockServer = new MockSonarQubeServer();

            var data = mockServer.Data;

            data.ServerProperties.Add("server.key", "server value 1");

            data.Languages.Add("invalid_plugin");

            var mockAnalyzerProvider = new MockRoslynAnalyzerProvider
            {
                SettingsToReturn = new AnalyzerSettings
                {
                    RulesetPath = "c:\\xxx.ruleset"
                }
            };

            var mockTargetsInstaller = new Mock <ITargetsInstaller>();
            var mockFactory          = new MockObjectFactory(mockServer, mockTargetsInstaller.Object, mockAnalyzerProvider);

            TeamBuildSettings settings;

            using (PreprocessTestUtils.CreateValidNonTeamBuildScope())
                using (new WorkingDirectoryScope(workingDir))
                {
                    settings = TeamBuildSettings.GetSettingsFromEnvironment(new TestLogger());
                    settings.Should().NotBeNull("Test setup error: TFS environment variables have not been set correctly");
                    settings.BuildEnvironment.Should().Be(BuildEnvironment.NotTeamBuild, "Test setup error: build environment was not set correctly");

                    var preProcessor = new TeamBuildPreProcessor(mockFactory, logger);

                    // Act
                    var success = preProcessor.Execute(CreateValidArgs("key", "name", "1.0")).Result;
                    success.Should().BeTrue("Expecting the pre-processing to complete successfully");
                }

            // Assert
            AssertDirectoriesCreated(settings);

            mockTargetsInstaller.Verify(x => x.InstallLoaderTargets(workingDir), Times.Once());
            mockServer.AssertMethodCalled("GetProperties", 1);
            mockServer.AssertMethodCalled("GetAllLanguages", 1);
            mockServer.AssertMethodCalled("TryGetQualityProfile", 0); // No valid plugin
            mockServer.AssertMethodCalled("GetRules", 0);             // No valid plugin

            AssertAnalysisConfig(settings.AnalysisConfigFilePath, 0, logger);

            // only contains SonarQubeAnalysisConfig (no rulesets or additional files)
            AssertDirectoryContains(settings.SonarConfigDirectory, Path.GetFileName(settings.AnalysisConfigFilePath));
        }
        public void PreProc_EndToEnd_SuccessCase()
        {
            // Checks end-to-end happy path for the pre-processor i.e.
            // * arguments are parsed
            // * targets are installed
            // * server properties are fetched
            // * rulesets are generated
            // * config file is created

            // Arrange
            var workingDir = TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext);
            var logger     = new TestLogger();

            // Configure the server
            var mockServer = new MockSonarQubeServer();

            var data = mockServer.Data;

            data.ServerProperties.Add("server.key", "server value 1");

            data.Languages.Add("cs");
            data.Languages.Add("vbnet");
            data.Languages.Add("another_plugin");

            data.AddQualityProfile("qp1", "cs", null)
            .AddProject("key")
            .AddRule(new SonarRule("csharpsquid", "cs.rule3"));

            data.AddQualityProfile("qp2", "vbnet", null)
            .AddProject("key")
            .AddRule(new SonarRule("vbnet", "vb.rule3"));

            var mockAnalyzerProvider = new MockRoslynAnalyzerProvider
            {
                SettingsToReturn = new AnalyzerSettings
                {
                    RulesetPath = "c:\\xxx.ruleset"
                }
            };

            var mockTargetsInstaller = new Mock <ITargetsInstaller>();
            var mockFactory          = new MockObjectFactory(mockServer, mockTargetsInstaller.Object, mockAnalyzerProvider);

            TeamBuildSettings settings;

            using (PreprocessTestUtils.CreateValidNonTeamBuildScope())
                using (new WorkingDirectoryScope(workingDir))
                {
                    settings = TeamBuildSettings.GetSettingsFromEnvironment(new TestLogger());
                    settings.Should().NotBeNull("Test setup error: TFS environment variables have not been set correctly");
                    settings.BuildEnvironment.Should().Be(BuildEnvironment.NotTeamBuild, "Test setup error: build environment was not set correctly");

                    var preProcessor = new TeamBuildPreProcessor(mockFactory, logger);

                    // Act
                    var success = preProcessor.Execute(CreateValidArgs("key", "name", "1.0")).Result;
                    success.Should().BeTrue("Expecting the pre-processing to complete successfully");
                }

            // Assert
            AssertDirectoriesCreated(settings);

            mockTargetsInstaller.Verify(x => x.InstallLoaderTargets(workingDir), Times.Once());
            mockServer.AssertMethodCalled("GetProperties", 1);
            mockServer.AssertMethodCalled("GetAllLanguages", 1);
            mockServer.AssertMethodCalled("TryGetQualityProfile", 2); // C# and VBNet
            mockServer.AssertMethodCalled("GetRules", 2);             // C# and VBNet

            AssertAnalysisConfig(settings.AnalysisConfigFilePath, 2, logger);
        }