示例#1
0
        public void TestQuickStart()
        {
            CommandLineRunner runner = new CommandLineRunner()
            {
                VoidMain = QuickStart.Main,
                Command  = "QuickStart"
            };
            var result = runner.Run();

            Assert.Equal(0, result.ExitCode);
        }
示例#2
0
        /// <summary>
        /// Converts to low-quality, small video
        /// </summary>
        /// <param name="inputPath">file location for original file</param>
        /// <param name="outputPath">file location for converted file</param>
        /// <param name="maxSeconds">0 if you don't want to truncate at all</param>
        /// <param name="progress">progress bar</param>
        /// <returns>log of the run</returns>
        public static ExecutionResult MakeLowQualitySmallVideo(string inputPath, string outputPath, int maxSeconds, IProgress progress)
        {
            if (string.IsNullOrEmpty(LocateAndRememberFFmpeg()))
            {
                return(new ExecutionResult()
                {
                    StandardError = "Could not locate FFMpeg"
                });
            }

            // isn't working: var arguments = "-i \"" + inputPath + "\" -vcodec mpeg4 -s 160x120 -b 800  -acodec libmp3lame -ar 22050 -ab 32k -ac 1 \"" + outputPath + "\"";
            var arguments = "-i \"" + inputPath +
                            "\" -vcodec mpeg4 -s 160x120 -b 800 -acodec libmp3lame -ar 22050 -ab 32k -ac 1 ";

            if (maxSeconds > 0)
            {
                arguments += " -t " + maxSeconds + " ";
            }
            arguments += "\"" + outputPath + "\"";

            progress.WriteMessage("ffmpeg " + arguments);

            var result = CommandLineRunner.Run(LocateAndRememberFFmpeg(),
                                               arguments,
                                               Environment.CurrentDirectory,
                                               60 * 10,          //10 minutes
                                               progress
                                               );

            progress.WriteVerbose(result.StandardOutput);


            //hide a meaningless error produced by some versions of liblame
            if (result.StandardError.Contains("lame: output buffer too small") &&
                File.Exists(outputPath))
            {
                result = new ExecutionResult
                {
                    ExitCode       = 0,
                    StandardOutput = result.StandardOutput,
                    StandardError  = string.Empty
                };
            }
            if (result.StandardError.ToLower().Contains("error") || //ffmpeg always outputs config info to standarderror
                result.StandardError.ToLower().Contains("unable to") ||
                result.StandardError.ToLower().Contains("invalid") ||
                result.StandardError.ToLower().Contains("could not"))
            {
                progress.WriteWarning(result.StandardError);
            }

            return(result);
        }
示例#3
0
        public void CommandWith10Line_CallbackOption_Get10LinesAsynchronously()
        {
            var progress = new StringBuilderProgress();
            int linesReceivedAsynchronously = 0;

            CommandLineRunner.Run(App, "CommandLineRunnerTest", null, string.Empty, 100,
                                  progress, s => ++ linesReceivedAsynchronously, null, true);
            // The test fails on Linux because progress gets called 10x for StdOutput plus
            // 1x for StdError (probably on the closing of the stream), so linesReceivedAsync is 11.
            // It also failes about 4% of the time on TC Windows agents
            Assert.AreEqual(10, linesReceivedAsynchronously);
        }
        public string Encode(string sourcePath, string destPathWithoutExtension)
        {
            string args    = string.Format("\"{0}\" \"{1}.{2}\"", sourcePath, destPathWithoutExtension, FormatName);
            string exePath = FileLocator.GetFileDistributedWithApplication("sox", "sox.exe");
            var    result  = CommandLineRunner.Run(exePath, args, "", 60, new ConsoleProgress());

            if (result.StandardError.Contains("FAIL"))
            {
                return(null);
            }
            return(destPathWithoutExtension + "." + FormatName);
        }
 public void LaunchDemoDialog()
 {
     using (var dlg = new ProgressDialogBackground())
     {
         dlg.ShowAndDoWork((progress, args) => CommandLineRunner.Run("PalasoUIWindowsForms.TestApp.exe", "CommandLineRunnerTest", null, string.Empty, 60, progress
                                                                     , (s) =>
         {
             progress.WriteStatus(s);
             progress.WriteVerbose(s);
         }));
     }
 }
示例#6
0
        public void ExecutionTest()
        {
            var command = "test -a test".Split(" ");

            var mapper = new ObjectMapper <Foo>();
            var target = mapper.Map(command);

            var runner = new CommandLineRunner <Foo>();

            runner.Run(target, command.First());

            Assert.Equal("test", target.Result);
        }
示例#7
0
        public void Stop()
        {
            if (string.IsNullOrEmpty(_pidFile) || !File.Exists(_pidFile))
            {
                return;
            }

            var pid = File.ReadAllText(_pidFile);

            CommandLineRunner.Run("kill", "-9 " + pid, Directory.GetCurrentDirectory(),
                                  120, new NullProgress());
            File.Delete(_pidFile);
            IsStarted = false;
        }
示例#8
0
        /// <summary>
        /// Converts to low-quality, mono mp3
        /// </summary>
        /// <returns>log of the run</returns>
        public static ExecutionResult MakeLowQualityCompressedAudio(string inputPath, string outputPath, IProgress progress)
        {
            if (string.IsNullOrEmpty(LocateAndRememberFFmpeg()))
            {
                return(new ExecutionResult()
                {
                    StandardError = "Could not locate FFMpeg"
                });
            }

            var arguments = "-i \"" + inputPath + "\" -acodec libmp3lame -ac 1 -ar 8000 \"" + outputPath + "\"";


            progress.WriteMessage("ffmpeg " + arguments);


            var result = CommandLineRunner.Run(LocateAndRememberFFmpeg(),
                                               arguments,
                                               Environment.CurrentDirectory,
                                               60 * 10,          //10 minutes
                                               progress
                                               );

            progress.WriteVerbose(result.StandardOutput);


            //hide a meaningless error produced by some versions of liblame
            if (result.StandardError.Contains("lame: output buffer too small") &&
                File.Exists(outputPath))
            {
                result = new ExecutionResult
                {
                    ExitCode       = 0,
                    StandardOutput = result.StandardOutput,
                    StandardError  = string.Empty
                };
            }
            if (result.StandardError.ToLower().Contains("error") ||
                result.StandardError.ToLower().Contains("unable to") ||
                result.StandardError.ToLower().Contains("invalid") ||
                result.StandardError.ToLower().Contains("could not")
                ) //ffmpeg always outputs config info to standarderror
            {
                progress.WriteError(result.StandardError);
            }

            return(result);
        }
示例#9
0
        /// <summary>
        /// Save the video file, first processing it with ffmpeg (if possible) to convert the data to a more
        /// common and more compressed format (h264 instead of vp8) and to insert keyframes every half second.
        /// Processing with ffmpeg also has the effect of setting the duration value for the video as a whole,
        /// something which is sadly lacking in the video data coming directly from mozilla browser code.
        /// If ffmpeg is not available, then the file is stored exactly as it comes from the api call.
        /// </summary>
        /// <remarks>
        /// Explicitly setting the frame rate to 30 fps is needed for Geckofx60.  The raw file that comes
        /// directly from the javascript objects claims to be at 1000fps.  This is perhaps due to the high
        /// speed video cameras that claim up to that frame rate.  I can't figure out how to change the frame
        /// rate in javascript.  The video track already claims to be at 30 fps even though the raw file
        /// claims to be at 1000fps.  Interestingly, setting the frame rate explicitly speeds up ffmpeg
        /// processing to what it was with Geckofx45 instead of being much slower.
        /// See https://issues.bloomlibrary.org/youtrack/issue/BL-7934.
        /// </remarks>
        private static void SaveVideoFile(string path, string rawVideoPath)
        {
            var length  = new FileInfo(rawVideoPath).Length;
            var seconds = (int)(length / 312500);             // we're asking for 2.5mpbs, which works out to 312.5K bytes per second.

            if (!string.IsNullOrEmpty(FfmpegProgram))
            {
                // -hide_banner = don't write all the version and build information to the console
                // -y = always overwrite output file
                // -v 16 = verbosity level reports only errors, including ones that can be recovered from
                // -i <path> = specify input file
                // -r 30 = set frame rate to 30 fps
                // -force_key_frames "expr:gte(t,n_forced*0.5)" = insert keyframe every 0.5 seconds in the output file
                var parameters = $"-hide_banner -y -v 16 -i \"{rawVideoPath}\" -r 30 -force_key_frames \"expr:gte(t,n_forced*0.5)\" \"{path}\"";
                // On slowish machines, this compression seems to take about 1/5 as long as the video took to record.
                // Allowing for some possibly being slower still, we're basing the timeout on half the length of the video,
                // plus a minute to be sure.
                var result = CommandLineRunner.Run(FfmpegProgram, parameters, "", seconds / 2 + 60, new NullProgress());
                var msg    = string.Empty;
                if (result.DidTimeOut)
                {
                    msg = LocalizationManager.GetString("EditTab.Toolbox.SignLanguage.Timeout",
                                                        "The initial processing of the video file timed out after one minute.  The raw video output will be stored.");
                }
                else
                {
                    var output = result.StandardError;
                    if (!string.IsNullOrWhiteSpace(output))
                    {
                        // Even though it may be possible to recover from the error, we'll just notify the user and use the raw vp8 output.
                        var format = LocalizationManager.GetString("EditTab.Toolbox.SignLanguage.VideoProcessingError",
                                                                   "Error output from ffmpeg trying to produce {0}: {1}{2}The raw video output will be stored.",
                                                                   "{0} is the path to the video file, {1} is the error message from the ffmpeg program, and {2} is a newline character");
                        msg = string.Format(format, path, output, Environment.NewLine);
                    }
                }
                if (!string.IsNullOrEmpty(msg))
                {
                    Logger.WriteEvent(msg);
                    ErrorReport.NotifyUserOfProblem(msg);
                    RobustFile.Copy(rawVideoPath, path, true);                         // use the original, hoping it's better than nothing.
                }
            }
            else
            {
                RobustFile.Copy(rawVideoPath, path, true);
            }
        }
示例#10
0
        protected virtual void when_executing_command(string args = null)
        {
            Console.WriteLine("> {0}-{1} {2}", Command.Verb, Command.Noun, args);
            args = args ?? string.Empty;
            foreach (var descriptor in Environment.ScopedDescriptors.Values)
            {
                descriptor.Save();
            }

            var runner = new CommandLineRunner();

            Results         = runner.Run(Command, args).ToList();
            CommandInstance = (T)runner.LastCommand;
            Results.ForEach(_ => _.ToString().Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None).Select(line => "< " + line).ToList().ForEach(Console.WriteLine));
            ReloadRepositories();
        }
示例#11
0
 public void Dispose()
 {
     try
     {
         // Delete table created from running the tests.
         CommandLineRunner runner = new CommandLineRunner()
         {
             Main    = TableAdmin.Main,
             Command = "TableAdmin"
         };
         runner.Run("deleteTable", TableId);
     }
     catch (RpcException ex) when(ex.Status.StatusCode == StatusCode.NotFound)
     {
     }
 }
示例#12
0
        /// <summary>
        /// Merge the specified input files into the specified output file. Returns null if successful,
        /// a string that may be useful in debugging if not.
        /// </summary>
        public static string MergeAudioFiles(IEnumerable <string> mergeFiles, string combinedAudioPath)
        {
            var ffmpeg = "/usr/bin/ffmpeg";             // standard Linux location

            if (SIL.PlatformUtilities.Platform.IsWindows)
            {
                ffmpeg = Path.Combine(BloomFileLocator.GetCodeBaseFolder(), "ffmpeg.exe");
            }
            if (RobustFile.Exists(ffmpeg))
            {
                // A command something like
                //   ffmpeg -i "concat:stereo1.mp3|monaural2.mp3|stereo3.mp3" -c:a libmp3lame output.mp3
                // might work okay except that the output file characteristics appear to depend on the
                // first file in the list, and stereo recorded on only one side does come out only on
                // that one side if the file ends up being stereo, but not if the file ends up monaural.
                // This may or may not be preferable to flattening all of the files to monaural at the
                // standard recording rate before concatenating them.  The current approach at least
                // has deterministic output for all files.
                var monoFiles = TryEnsureConsistentInputFiles(ffmpeg, mergeFiles);
                try
                {
                    var argsBuilder = new StringBuilder("-i \"concat:");
                    argsBuilder.Append(string.Join("|", monoFiles));
                    argsBuilder.Append($"\" -c copy \"{combinedAudioPath}\"");
                    var result = CommandLineRunner.Run(ffmpeg, argsBuilder.ToString(), "", 60 * 10, new NullProgress());
                    var output = result.ExitCode != 0 ? result.StandardError : null;
                    if (output != null)
                    {
                        RobustFile.Delete(combinedAudioPath);
                    }
                    return(output);
                }
                finally
                {
                    foreach (var file in monoFiles)
                    {
                        if (!mergeFiles.Contains(file))
                        {
                            RobustFile.Delete(file);
                        }
                    }
                }
            }

            return("Could not find ffmpeg");
        }
示例#13
0
 public void Dispose()
 {
     try
     {
         // Delete database created from running the tests.
         CommandLineRunner runner = new CommandLineRunner()
         {
             Main    = Program.Main,
             Command = "Spanner"
         };
         runner.Run("deleteDatabase",
                    ProjectId, InstanceId, DatabaseId);
     }
     catch (RpcException ex) when(ex.Status.StatusCode == StatusCode.NotFound)
     {
     }
 }
示例#14
0
        public void CanOpenAndRunSpecifcStateAndOutputToFileWithCommandLineRunner()
        {
            string openpath = Path.Combine(TestDirectory, @"core\commandline\addmultwithstatesindyn.dyn");
            var    newPath  = GetNewFileNameOnTempPath("xml");

            var    runner        = new CommandLineRunner(this.CurrentDynamoModel);
            string commandstring = "/o" + " " + openpath + " " + "/s" + " " + "state2" + " " + "/v" + " " + newPath;

            runner.Run(CommandstringToArgs(commandstring));

            var output = new XmlDocument();

            output.Load(newPath);
            AssertOutputValuesForGuid("6e2d89d1-d5e8-4030-b065-f9d98b3adb45", new List <Tuple <int, string> > {
                Tuple.Create(0, "31")
            }, output);
        }
示例#15
0
        /// <summary>
        /// Epub preview cannot play an audio file that contains a mixture of stereo and monaural
        /// sections.  It also cannot play an audio file that contains segments recorded at
        /// different rates.  We concatenate all narration files used on a page together for epubs
        /// to use, so we need to ensure that resulting audio file is all of one type at one rate.
        /// (which we default to monaural at 44100 Hz, which seems to be a standard default)
        /// Scan through the input file list, checking whether each file has been recorded in stereo
        /// or mono.  If it was recorded in stereo, create a monaural version of the file for
        /// concatenating with the other files in the list.  If the file was recorded at a rate
        /// other than 44100 Hz, create a version with that recording rate.
        /// If there's only one file in the list, just return the input list.
        /// If any file fails to convert for any reason, it is returned in the output list.  So the
        /// files in the output list may not really be consistent in reality...
        /// </summary>
        /// <remarks>
        /// See https://issues.bloomlibrary.org/youtrack/issue/BL-9051
        /// and https://issues.bloomlibrary.org/youtrack/issue/BL-9100.
        /// </remarks>
        private static IEnumerable <string> TryEnsureConsistentInputFiles(string ffmpeg, IEnumerable <string> mergeFiles)
        {
            if (mergeFiles.Count() < 2)
            {
                return(mergeFiles);
            }
            var monoFiles   = new List <string>();
            var argsBuilder = new StringBuilder();

            foreach (var file in mergeFiles)
            {
                var args   = $"-hide_banner -i \"{file}\" -f null -";
                var result = CommandLineRunner.Run(ffmpeg, args, "", 60, new NullProgress());
                var output = result.StandardError;
                var match  = Regex.Match(output, "Audio: [^,]*, ([0-9]+) Hz, ([a-z]+), [^,]*, ([0-9]+) kb/s");
                if (match.Success)
                {
                    // Get a mono version at 44100 Hz of the sound file, trying to preserve its quality.
                    var recordRate = match.Groups[1].ToString();
                    var recordType = match.Groups[2].ToString();
                    var bitRate    = match.Groups[3].ToString();
                    if (recordType == "stereo" || recordRate != "44100")
                    {
                        var tempFile = TempFile.CreateAndGetPathButDontMakeTheFile();
                        tempFile.Detach();
                        args = $"-i \"{file}\" -ac 1 -ar 44100 -b:a {bitRate}k \"{tempFile.Path}.mp3\"";
                        Debug.WriteLine($"DEBUG: ffmpeg {args}");
                        result = CommandLineRunner.Run(ffmpeg, args, "", 120, new NullProgress());
                        if (result.ExitCode == 0)
                        {
                            monoFiles.Add(tempFile.Path + ".mp3");
                            continue;
                        }
                        else
                        {
                            Logger.WriteEvent($"Error converting {file} to monaural at 44100 Hz" + Environment.NewLine + result.StandardError);
                            Debug.WriteLine($"Error converting {file} to monaural at 44100 Hz");
                            Debug.WriteLine(result.StandardError);
                        }
                    }
                }
                monoFiles.Add(file);
            }
            return(monoFiles);
        }
示例#16
0
        public void Can_deploy_to_directory()
        {
            // setup
            var deployDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DeploymentDirectory");
            if (Directory.Exists(deployDirectory))
                Directory.Delete(deployDirectory, true);
            Directory.CreateDirectory(deployDirectory);
            var writer = new ConsoleWriter();
            var runContext = new RunContext();
            var runner = new CommandLineRunner(writer,
                new PackageProcessor(new ActionExecutor(writer, runContext), writer, new NuGetProcess(writer), runContext),
                new NullActionExecutor(),
                runContext);
            SetDefinitions(new Packages
            {
                Items = new object[]
                {
                    new Package
                    {
                        BasePath = _baseDirectory,
                        name = "package 1",
                        NuSpecPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestData/TestNuSpec.nuspec"),
                        OutputDirectory = _outputDirectory,
                        Version = "",
                        Deployments = new PackageDeployments
                        {
                            Deployment = new[]
                            {
                                new Deployment
                                {
                                    name = "test deployment",
                                    path = deployDirectory
                                }
                            }
                        }
                    }
                }
            });

            // act
            runner.Run(_rootDirectory, _nugetLocation, _defintionsFileLocation, "", new Dictionary<string, string>());

            // assert
            Assert.IsTrue(File.Exists(Path.Combine(deployDirectory, "package1.1.2.3.nupkg")));
        }
示例#17
0
        public void Encode(string sourcePath, string destPathWithoutExtension, IProgress progress)
        {
            LocateAndRememberLAMEPath();

            if (RobustFile.Exists(destPathWithoutExtension + ".mp3"))
            {
                RobustFile.Delete(destPathWithoutExtension + ".mp3");
            }

            progress.WriteMessage(LocalizationManager.GetString("LameEncoder.Progress", " Converting to mp3", "Appears in progress indicator"));

            //-a downmix to mono
            string arguments = string.Format("-a \"{0}\" \"{1}.mp3\"", sourcePath, destPathWithoutExtension);
            //ClipRepository.RunCommandLine(progress, _pathToLAME, arguments);
            ExecutionResult result = CommandLineRunner.Run(_pathToLAME, arguments, null, 60, progress);

            result.RaiseExceptionIfFailed("");
        }
示例#18
0
        public void CanOpenAndRunAllImportedStatesWithCommandLineRunner()
        {
            string openPath    = Path.Combine(TestDirectory, @"core\commandline\addmultwithoutstates.dyn");
            string presetsPath = Path.Combine(TestDirectory, @"core\commandline\statesOnly.xml");
            var    newPath     = GetNewFileNameOnTempPath("xml");

            var    runner        = new CommandLineRunner(this.CurrentDynamoModel);
            string commandstring = "/o" + " " + openPath + " " + "/s" + " " + "all" + " " + "/p" + " " + presetsPath + " " + "/v" + " " + newPath;

            runner.Run(CommandstringToArgs(commandstring));

            var output = new XmlDocument();

            output.Load(newPath);
            AssertOutputValuesForGuid("6e2d89d1-d5e8-4030-b065-f9d98b3adb45", new List <Tuple <int, string> > {
                Tuple.Create(0, "10"), Tuple.Create(0, "31"), Tuple.Create(0, "20")
            }, output);
        }
示例#19
0
        public void Start()
        {
            _pidFile = Path.GetTempFileName();
            var args = "serv --port 0 --daemon --config web.push_ssl=No --config \"web.allow_push=*\" --pid-file "
                       + _pidFile;
            var result = CommandLineRunner.Run(MercurialTestHelper.HgCommand,
                                               args, RepoPath, 120, new NullProgress());

            Assert.That(result.ExitCode, Is.EqualTo(0),
                        string.Format("hg {0}\nStdOut: {1}\nStdErr: {2}", args,
                                      result.StandardOutput, result.StandardError));
            var regex = new Regex("^listening at ([^ ]+)");

            Assert.That(regex.IsMatch(result.StandardOutput), Is.True);
            var match = regex.Match(result.StandardOutput);

            Url       = match.Groups[1].Captures[0].Value;
            IsStarted = true;
        }
示例#20
0
        /// <summary>
        /// Creates an audio file, using the received one as the bases, with the specified number
        /// of channels. For example, this can be used to convert a 2-channel audio file to a
        /// single channel audio file.
        /// </summary>
        /// <returns>log of the run</returns>
        public static ExecutionResult ChangeNumberOfAudioChannels(string inputPath,
                                                                  string outputPath, int channels, IProgress progress)
        {
            if (string.IsNullOrEmpty(LocateFFmpeg()))
            {
                return new ExecutionResult {
                           StandardError = "Could not locate FFMpeg"
                }
            }
            ;

            var arguments = string.Format("-i \"{0}\" -vn -ac {1} \"{2}\"",
                                          inputPath, channels, outputPath);

            var result = CommandLineRunner.Run(LocateAndRememberFFmpeg(),
                                               arguments,
                                               Environment.CurrentDirectory,
                                               60 * 10, //10 minutes
                                               progress);

            progress.WriteVerbose(result.StandardOutput);

            //hide a meaningless error produced by some versions of liblame
            if (result.StandardError.Contains("lame: output buffer too small") && File.Exists(outputPath))
            {
                var doctoredResult = new ExecutionResult
                {
                    ExitCode       = 0,
                    StandardOutput = result.StandardOutput,
                    StandardError  = string.Empty
                };

                return(doctoredResult);
            }

            // ffmpeg always outputs config info to standarderror
            if (result.StandardError.ToLower().Contains("error"))
            {
                progress.WriteError(result.StandardError);
            }

            return(result);
        }
        private (List <string> Log, bool Succeeded, Exception Error) Run(string what, string where)
        {
            var command = $"lighthouse run --what {what} --where {where}";

            var typeFactory = new TypeFactory();

            // just create a dumb network, that will let the console run and fail expectedly
            var virtualNetwork = new VirtualNetwork();

            typeFactory.Register <INetworkProvider>(() => virtualNetwork);

            var pingContainer = Substitute.For <ILighthouseServiceContainer>();

            virtualNetwork.Register(pingContainer); //, where.ToUri());

            RemoteAppRunRequest receivedRequest = null;
            var returnValue = new RemoteAppRunHandle(Guid.NewGuid().ToString());

            pingContainer.HandleRequest <RemoteAppRunRequest, RemoteAppRunHandle>(Arg.Do <RemoteAppRunRequest>(r => receivedRequest = r)).Returns(returnValue);

            var consoleWrites = new List <string>();
            var runner        = new CommandLineRunner((log) => {
                consoleWrites.Add(log);
                Output.WriteLine(log);
            }, () => "no_console_reads", typeFactory);

            try
            {
                var returnCode = runner.Run(command.Split(" ").Skip(1));
                receivedRequest.Should().NotBeNull();

                // the response just roundtrips the request
                receivedRequest.What.Should().Be(what);
                return(consoleWrites, true, null);
            }
            catch (Exception e)
            {
                return(consoleWrites, false, e);
            }
        }
示例#22
0
        // Run ffmpeg on the file to get statistics.
        // request is an optional parameter, the method works fine with it set to null.
        private static string RunFfmpegOnVideoToGetStatistics(ApiRequest request, string videoFilePath)
        {
            // -hide_banner = don't write all the version and build information to the console
            // -i <path> = specify input file
            var parameters = $"-hide_banner -i \"{videoFilePath}\"";
            var result     = CommandLineRunner.Run(FfmpegProgram, parameters, "", 60, new NullProgress());

            if (result.DidTimeOut)
            {
                request?.Failed("ffmpeg timed out getting video statistics");
                return(string.Empty);
            }

            var output = result.StandardError;

            if (string.IsNullOrWhiteSpace(output))
            {
                request?.Failed("ffmpeg failed to get video statistics");
                return(string.Empty);
            }

            return(output);
        }
示例#23
0
 void InitializeDatabase()
 {
     // If the database has not been initialized, retry.
     _spannerCmd.Run("createSampleDatabase",
                     _fixture.ProjectId, _fixture.InstanceId, _fixture.DatabaseId);
 }
示例#24
0
 public void Dispose()
 {
     try
     {
         // Delete database created from running the tests.
         _spannerCmd.Run("deleteSampleDatabase",
                         s_projectId, s_instanceId, s_databaseId);
     }
     catch (RpcException ex) when(ex.Status.StatusCode == StatusCode.NotFound)
     {
     }
 }
        private string FindAceByDaisyOrTellUser(ApiRequest request)
        {
            _webSocketProgress.Message("FindingAce", "Finding Ace by DAISY on this computer...");
            var whereProgram = Platform.IsWindows ? "where" : "which";
            var npmFileName  = Platform.IsWindows ? "npm.cmd" : "npm";
            var whereResult  = CommandLineRunner.Run(whereProgram, npmFileName, Encoding.ASCII, "", 2, new NullProgress());

            if (!String.IsNullOrEmpty(whereResult.StandardError))
            {
                _webSocketProgress.ErrorWithoutLocalizing(whereResult.StandardError);
            }
            if (!whereResult.StandardOutput.Contains(npmFileName))
            {
                ReportErrorAndFailTheRequest(request, whereResult, "Could not find npm.");
                return(null);
            }

            var fullNpmPath = whereResult.StandardOutput.Split('\n')[0].Trim();
            // note: things like nvm will mess with where the global node_modules lives. The best way seems to be
            // to ask npm:
            var result = CommandLineRunner.Run(npmFileName, "root -g", Encoding.ASCII, Path.GetDirectoryName(fullNpmPath), 10,
                                               new NullProgress());

            const string kCoreError = "Could not get \"npm -g root\" to work. Is Node & npm installed and working?";

            if (result == null)
            {
                // I don't think this could happen, but *something* was null for Sue.
                ReportErrorAndFailTheRequest(request, whereResult, $"{kCoreError} CommandLineRunner.Run() returned null.");
                return(null);
            }
            if (!string.IsNullOrWhiteSpace(result.StandardError))
            {
                ReportErrorAndFailTheRequest(request, whereResult, $"{kCoreError} <br>StandardError:<br>" + result.StandardError);
                return(null);
            }
            if (result.StandardOutput == null)
            {
                ReportErrorAndFailTheRequest(request, whereResult, $"{kCoreError} StandardOutput was null.");
                return(null);
            }

            if (!result.StandardOutput.Contains("node_modules"))
            {
                ReportErrorAndFailTheRequest(request, whereResult, kCoreError);
                return(null);
            }

            var nodeModulesDirectory = result.StandardOutput.Trim();

            if (!Directory.Exists((nodeModulesDirectory)))
            {
                ReportErrorAndFailTheRequest(request, whereResult, "Could not find global node_modules directory");
                return(null);
            }

            // if they installed via npm install -g  @daisy/ace
            var daisyDirectory = Path.Combine(nodeModulesDirectory, "@daisy/ace/bin/");

            if (!Directory.Exists((daisyDirectory)))
            {
                // if they just installed via npm install -g  @daisy/ace-cli
                daisyDirectory = Path.Combine(nodeModulesDirectory, "@daisy/ace-cli/bin/");
                if (!Directory.Exists((daisyDirectory)))
                {
                    ReportErrorAndFailTheRequest(request, whereResult, $"Could not find daisy-ace at {daisyDirectory}.");
                    return(null);
                }
            }
            _webSocketProgress.Message("FoundAce", "Found.");
            return(daisyDirectory);
        }
        private void MakeAceByDaisyReport(ApiRequest request)
        {
            // First check whether ace has been installed.
            var daisyDirectory = FindAceByDaisyOrTellUser(request);             // this method does the request.fail() if needed

            if (string.IsNullOrEmpty(daisyDirectory))
            {
                return;
            }
            // As of version 1.0.2, the ace report has stylesheets on the internet.  See https://issues.bloomlibrary.org/youtrack/issue/BL-6118.
            // To be specific, https://cdn.datatables.net/1.10.15/css/dataTables.bootstrap4.min.css and
            // https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css.
            if (!UrlLookup.CheckGeneralInternetAvailability(true))
            {
                _webSocketProgress.ErrorWithoutLocalizing(
                    "Sorry, you must have an internet connection in order to view the Ace by DAISY report.");
                request.Failed();
                return;
            }

            var reportRootDirectory = Path.Combine(System.IO.Path.GetTempPath(), "daisy-ace-reports");

            // Do our best at clearing out previous runs.
            // This call is ok if the directory does not exist at all.
            SIL.IO.RobustIO.DeleteDirectoryAndContents(reportRootDirectory);
            // This call is ok if the above failed and it still exists
            Directory.CreateDirectory(reportRootDirectory);

            // was having a problem with some files from previous reports getting locked.
            // so give new folder names if needed
            var haveReportedError = false;
            var errorMessage      = "Unknown Error";

            var version = GetAceByDaisyVersion(daisyDirectory);

            if (version.old)
            {
                _webSocketProgress.MessageWithoutLocalizing(
                    $"You appear to have an older version ({version.version}) of ACE by Daisy. This may cause problems.",
                    ProgressKind.Warning);
                _webSocketProgress.MessageWithoutLocalizing(
                    "We recommend you run \"npm install @daisy/ace -g\" from a command line to get the latest.",
                    ProgressKind.Warning);
            }

            var started = DateTime.Now;

            var epubPath = MakeEpub(reportRootDirectory, _webSocketProgress);

            // Try 3 times. It could be that this is no longer needed, but working on a developer
            // machine isn't proof.
            for (var i = 0; i < 3; i++)
            {
                var randomName      = Guid.NewGuid().ToString();
                var reportDirectory = Path.Combine(reportRootDirectory, randomName);

                var       arguments             = $"ace.js --verbose -o \"{reportDirectory}\" \"{epubPath}\"";
                const int kSecondsBeforeTimeout = 60;
                var       progress = new NullProgress();
                _webSocketProgress.MessageWithoutLocalizing("Running Ace by DAISY");

                ExecutionResult res    = null;
                string          ldpath = null;
                try
                {
                    // Without this variable switching on Linux, the chrome inside ace finds the
                    // wrong version of a library as part of our mozilla code.
                    ldpath = Environment.GetEnvironmentVariable("LD_LIBRARY_PATH");
                    Environment.SetEnvironmentVariable("LD_LIBRARY_PATH", null);
                    res = CommandLineRunner.Run("node", arguments, Encoding.UTF8, daisyDirectory, kSecondsBeforeTimeout,
                                                progress,
                                                (dummy) => { });
                }
                finally
                {
                    // Restore the variable for our next geckofx browser to find.
                    if (!String.IsNullOrEmpty(ldpath))
                    {
                        Environment.SetEnvironmentVariable("LD_LIBRARY_PATH", ldpath);
                    }
                }

                if (res.DidTimeOut)
                {
                    errorMessage = $"Daisy Ace timed out after {kSecondsBeforeTimeout} seconds.";
                    _webSocketProgress.ErrorWithoutLocalizing(errorMessage);
                    continue;
                }

                var answerPath = Path.Combine(reportDirectory, "report.html");
                if (!File.Exists(answerPath))
                {
                    // This hasn't been effectively reproduced, but there was a case where this would fail at least
                    // half the time on a book, reproducable. That book had 2 pages pointing at placeholder.png,
                    // and we were getting an error related to it being locked. So we deduce that ace was trying
                    // to copy the file twice, at the same time (normal nodejs code is highly async).
                    // Now the problem is not reproducable, but I'm leaving in this code that tried to deal with it.
                    errorMessage = $"Exit code{res.ExitCode}{Environment.NewLine}" +
                                   $"Standard Error{Environment.NewLine}{res.StandardError}{Environment.NewLine}" +
                                   $"Standard Out{res.StandardOutput}";

                    _webSocketProgress.ErrorWithoutLocalizing(errorMessage);

                    continue;                     // something went wrong, try again
                }

                // The html client is set to treat a text reply as a url of the report. Make sure it's valid for being a URL.
                // See https://silbloom.myjetbrains.com/youtrack/issue/BL-6197.
                request.ReplyWithText("/bloom/" + answerPath.EscapeFileNameForHttp());
                if (version.old)
                {
                    // If we displayed an important message about updating ACE, make sure the user
                    // has SOME time to see it.
                    // Review: is this long enough? Should we look for some other way to show the
                    // problem? At present the problems caused by an old version (1.1 is the oldest
                    // contemporary with Bloom) is fairly minor.
                    while (DateTime.Now - started < new TimeSpan(0, 0, 0, 5))
                    {
                        Thread.Sleep(100);
                    }
                }
                return;
            }

            // If we get this far, we give up.
            ReportErrorAndFailTheRequest(request, errorMessage);
        }
示例#27
0
        public void Nuspec_overrides_package_and_global_level_versions()
        {
            // setup
            var writer = new ConsoleWriter();
            var runContext = new RunContext();
            var runner = new CommandLineRunner(writer,
                new PackageProcessor(new ActionExecutor(writer, runContext), writer, new NuGetProcess(writer), runContext),
                new NullActionExecutor(),
                runContext);
            SetDefinitions(new Packages
            {
                Items = new object[]
                {
                    new Package
                    {
                        BasePath = _baseDirectory,
                        name = "package 1",
                        NuSpecPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestData/TestNuSpec.nuspec"),
                        OutputDirectory = _outputDirectory,
                        Version = "4.0.1"
                    }
                }
            });

            // act
            runner.Run(_rootDirectory, _nugetLocation, _defintionsFileLocation, "5.0.1", new Dictionary<string, string>());

            // assert
            Assert.IsTrue(File.Exists(Path.Combine(_outputDirectory, "package1.1.2.3.nupkg")));
        }
示例#28
0
 void InitializeDatabase()
 {
     // If the database has not been initialized, retry.
     _spannerCmd.Run("createSampleDatabase",
                     _fixture.ProjectId, _fixture.InstanceId, _fixture.DatabaseId);
     _spannerCmd.Run("insertSampleData",
                     _fixture.ProjectId, _fixture.InstanceId, _fixture.DatabaseId);
     _spannerCmd.Run("insertStructSampleData",
                     _fixture.ProjectId, _fixture.InstanceId, _fixture.DatabaseId);
     _spannerCmd.Run("addColumn",
                     _fixture.ProjectId, _fixture.InstanceId, _fixture.DatabaseId);
     _spannerCmd.Run("addCommitTimestamp",
                     _fixture.ProjectId, _fixture.InstanceId, _fixture.DatabaseId);
     _spannerCmd.Run("addIndex",
                     _fixture.ProjectId, _fixture.InstanceId, _fixture.DatabaseId);
 }
示例#29
0
 public QuickStartTests(QuickStartFixture fixture)
 {
     _fixture = fixture;
     _spannerCmd.Run("createDatabase",
                     _fixture.ProjectId, _fixture.InstanceId, _fixture.DatabaseId);
 }
示例#30
0
        public void Error_when_proccessing_nuspec_without_global_or_package_version()
        {
            // setup
            var writer = new Mock<IConsoleWriter>();
            writer.Setup(x => x.WriteMessage(It.IsAny<string>()));
            writer.Setup(x => x.WriteError(It.IsAny<string>()));
            var runContext = new RunContext();
            var runner = new CommandLineRunner(writer.Object,
                new PackageProcessor(new ActionExecutor(writer.Object, runContext), writer.Object, new NuGetProcess(writer.Object), runContext),
                new NullActionExecutor(),
                runContext);
            SetDefinitions(new Packages
            {
                Items = new object[]
                {
                    new Package
                    {
                        BasePath = _baseDirectory,
                        name = "package 1",
                        NuSpecPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestData/TestNuSpecWithoutVersion.nuspec"),
                        OutputDirectory = _outputDirectory,
                        Version = ""
                    }
                }
            });

            // act
            runner.Run(_rootDirectory, _nugetLocation, _defintionsFileLocation, "", new Dictionary<string, string>());

            // assert
            writer.Verify(
                x =>
                x.WriteError("The nuspec for package \"package 1\" expects a version to be supplied but the package didn't define one and also there wasn't a version inputed via the parameter -v."));
        }
示例#31
0
        public void Invalid_defintions_file_writes_error()
        {
            // setup
            var writer = new Mock<IConsoleWriter>();
            writer.Setup(x => x.WriteError("Error with definitions file: The 'Invalid' start tag on line 1 position 51 does not match the end tag of 'Packages'. Line 1, position 61."));
            var runner = new CommandLineRunner(writer.Object, new NullPackageProcessor(), new NullActionExecutor(), new RunContext());
            var invalidXmlFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "invaidxml.xml");
            if (File.Exists(invalidXmlFile))
                File.Delete(invalidXmlFile);
            File.WriteAllText(invalidXmlFile, "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Packages><Invalid></Packages>");

            // act
            runner.Run(_rootDirectory, _nugetLocation, invalidXmlFile, string.Empty, new Dictionary<string, string>());

            // assert
            writer.Verify(x => x.WriteError("Error with definitions file: The 'Invalid' start tag on line 1 position 51 does not match the end tag of 'Packages'. Line 1, position 61."));
        }
示例#32
0
 void InitializeDatabase()
 {
     // If the database has not been initialized, retry.
     _spannerCmd.Run("dropSampleTables",
                     s_projectId, s_instanceId, s_databaseId);
     _spannerCmd.Run("createSampleDatabase",
                     s_projectId, s_instanceId, s_databaseId);
     _spannerCmd.Run("insertSampleData",
                     s_projectId, s_instanceId, s_databaseId);
     _spannerCmd.Run("addColumn",
                     s_projectId, s_instanceId, s_databaseId);
 }
示例#33
0
        void TestAnalyzeNoArgsSucceeds()
        {
            ConsoleOutput output = _analyze.Run();

            Assert.Equal(0, output.ExitCode);
        }
示例#34
0
        public void No_packages_or_commands_writes_warning()
        {
            // setup
            var writer = new Mock<IConsoleWriter>();
            writer.Setup(x => x.WriteWarning("There are no packages or pre/post commands defined."));
            var runner = new CommandLineRunner(writer.Object, new NullPackageProcessor(), new NullActionExecutor(), new RunContext());
            var validXmlFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "validxml.xml");
            if (File.Exists(validXmlFile))
                File.Delete(validXmlFile);
            File.WriteAllText(validXmlFile, "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Packages></Packages>");

            // act
            runner.Run(_rootDirectory, _nugetLocation, validXmlFile, string.Empty, new Dictionary<string, string>());

            // assert
            writer.Verify(x => x.WriteWarning("There are no packages or pre/post commands defined."));
        }
示例#35
0
 void InitializeDatabase()
 {
     // If the database has not been initialized, retry.
     try
     {
         QuerySampleData();
     }
     catch (AggregateException e) when(ContainsError(e, ErrorCode.NotFound))
     {
         // The database does not exist.  Create database and retry.
         _spannerCmd.Run("createSampleDatabase",
                         s_projectId, s_instanceId, s_databaseId);
         _spannerCmd.Run("insertSampleData",
                         s_projectId, s_instanceId, s_databaseId);
         QuerySampleData();
     }
     catch (XunitException)
     {
         // The database does not contain the expected datae.
         // Insert sample data and retry.
         _spannerCmd.Run("insertSampleData",
                         s_projectId, s_instanceId, s_databaseId);
         QuerySampleData();
     }
     try
     {
         _spannerCmd.Run("addColumn",
                         s_projectId, s_instanceId, s_databaseId);
     }
     catch (AggregateException e) when(ContainsError(e, ErrorCode.AlreadyExists))
     {
     }
 }
示例#36
0
        public void Throws_error_if_nuget_doesnt_exist()
        {
            var commandLineRunner = new CommandLineRunner(new ConsoleWriter(), new NullPackageProcessor(), new NullActionExecutor(), new RunContext());

            try
            {
                commandLineRunner.Run(_rootDirectory, "C:\\no\\where.exe", _defintionsFileLocation, string.Empty, new Dictionary<string, string>());
            }
            catch (Exception ex)
            {
                Assert.AreEqual("The nuget location \"C:\\no\\where.exe\" doesn't exist.", ex.Message);
                return;
            }

            Assert.Fail("No error thrown");
        }