Chrono Mock
IdiomaPortuguês (Brasil)

Referência da linha de comando

Todas as opções dos dois comandos, as duas tabelas de códigos de saída e como ler o que volta. A versão narrativa, com o raciocínio, está na página CLI e CI.

Dois comandos

chrono run inicia um aplicativo em outra data e hora. chrono calc calcula uma data e diz o que a torna interessante. Os dois compartilham uma gramática de passos, então um deslocamento escrito para um significa o mesmo no outro.

chrono version responde a uma terceira pergunta, bem menor: qual é esta versão, qual dos dois núcleos é o executável e qual versão do protocolo ele fala. Uma linha na saída padrão, para que um script possa capturá-la.

chrono license responde à quarta: sob qual licença esta versão é distribuída, o aviso de isenção de garantia e os componentes de terceiros vinculados a ela. Também diz onde ficam no disco o texto completo da licença e os avisos de terceiros, ou admite quando a cópia que você está executando não os tem ao lado. --components lista cada componente incluído com a sua versão, em vez de um resumo.

chrono presets lista o catálogo de cenários do jeito que --preset o lê: cada cenário da pasta, escrito com as palavras que a gramática da calculadora lê, e cada arquivo que ele recusaria, com o motivo. --json escreve chronomock.presets/1 e --dir indica outra pasta.

chrono run <target> [options]
chrono calc [options]
chrono version        # chrono 0.4.0 (x64, protocol 1)
chrono license        # GPL-3.0-only, and what is bundled
chrono presets        # o catálogo, do jeito que --preset o lê
chrono --help          # usage for all of them

chrono run - opções

OpçãoO que faz
--at <moment> O momento em que começar, no fuso da sessão. Absoluto (2038-01-19T03:14:07) ou relativo com um sinal à frente (+1d, -2h). Unidades: s m h d w mo q y - m é minuto e mo é mês. Sem esta opção, o relógio da sessão começa na hora real atual, então --mode xN sozinho apenas faz o alvo correr mais rápido.
--zone +HH:MM O fuso da sessão: o fuso em que o momento é escrito e o que as chamadas de hora local do alvo informam. Um deslocamento fixo, sem horário de verão. Sem ela, o fuso do próprio host.
--mode flow|frozen|xN flow corre em velocidade real, frozen mantém o relógio parado, xN o faz correr N vezes mais rápido (x60 transforma uma hora em um minuto, x1440 um dia).
--scale-duration Acelerar também o eixo do tempo decorrido: contadores de ticks, tempo de interrupção, pausas e temporizadores. As esperas por objetos são contadas e mantêm a duração real. Desligado por padrão, porque um relógio de parede e um cronômetro são perguntas diferentes. Um temporizador ou um atraso marcado para uma data e hora segue o relógio da sessão com ou sem esta opção.
--scale-qpc Escala também o contador de alta resolução, de onde Python 3.13+ monotonic, .NET Stopwatch e Java nanoTime leem o tempo decorrido. Desativado por padrão: um aplicativo que mede a própria renderização com esse contador pode parecer distorcido.
--ticks N Encerra a sessão após N batimentos, de um segundo real cada, e relata. Sem ela, a ferramenta continua anexada até que o alvo, e todo programa que ele iniciou e que roda no relógio da sessão, tenha terminado - um inicializador que termina logo deixa a sessão com o aplicativo que ele iniciou.
--timeout <s> Desiste após esse número de segundos e sai com 6, para um pipeline que não pode travar. Independentemente desta opção, um núcleo que fica 15 segundos em silêncio é parado e também sai com 6 - nos dois casos a execução é interrompida, então não traz veredito.
--args "..." Argumentos para o alvo, como uma única string, divididos pela mesma regra que o Windows usa - assim um argumento com espaços sobrevive. Para um alvo Chromium, --user-data-dir e --remote-debugging-port são recusados em vez de sobrescritos: a sessão precisa do próprio perfil isolado, e rodar em silêncio no seu perfil real do navegador é a única coisa que não pode acontecer.
--cwd <dir> Inicia o alvo nesse diretório. Sem ela, o alvo herda o nosso, que é o que toda execução fazia antes de esta opção existir. Um valor vazio é um erro de uso e não “nenhum diretório” - ausente e vazio são coisas diferentes, e só o ausente é algo que o Windows pode receber. Um diretório que não existe interrompe a sessão com target.cwd_missing antes de qualquer coisa ser iniciada, em vez de aparecer depois como um alvo que não quis iniciar.
--preset <id> Pega o momento e a velocidade de presets/<id>.json. Exclusiva com --at, --mode e --scale-duration, já que o cenário é então a única fonte dos dois.
--param id=value Preenche um parâmetro do cenário. Repetível, exige --preset. Somente em run, a data de início de um teste assume por padrão a data de criação do próprio executável alvo, de modo que um cenário de teste conta a partir do dia em que o aplicativo foi instalado sem que você precise digitá-la.
--set-after T:M No batimento T, muda a velocidade para M. Em andamento, o multiplicador é de no mínimo 1 - congelar no meio da sessão não é oferecido aqui.
--jump-after T:moment No batimento T, faz o relógio saltar para esse momento, absoluto ou relativo, no fuso da sessão.
--force Mantém a sessão mesmo quando o veredito inicial diz que a substituição não teve efeito - por padrão o alvo é parado, porque uma sessão que não provou nada é pior que nenhuma sessão. O veredito não muda, nem o código de saída. Isto só decide se o alvo continua rodando.
--no-embedded Deixa as páginas web dentro do aplicativo (WebView2, Qt WebEngine) no relógio real e não abre porta de depuração. Sem ela, a sessão pede a esse motor que abra uma porta local e coloca as páginas dele no relógio da sessão por meio dela - enquanto a porta está aberta, qualquer outro programa neste computador pode usá-la para alcançar essas páginas.
--elevated-embedded Para um aplicativo que roda como administrador, a partir de um Chrono Mock que também roda como administrador. O WebView2 ignora, para um aplicativo assim, a configuração pela qual a sessão alcança as páginas dele, então a sessão grava um valor no Registro da máquina (HKLM, com o nome do .exe do aplicativo) durante a sua duração e o remove no final. Enquanto o aplicativo roda, qualquer outro programa neste computador pode alcançar as páginas dele pela porta, e o aplicativo tem direitos de administrador. Não com --no-embedded.
--keep-background-timers Inicia o motor web - o navegador de um aplicativo Chromium ou Electron, ou o motor dentro de um aplicativo - com a desaceleração dos temporizadores em janelas ocultas desligada, para que uma janela minimizada mantenha a velocidade da sessão. O aplicativo também trabalha então em ritmo total enquanto está oculto. Um aplicativo iniciado como administrador por meio de --elevated-embedded não a recebe.
--dry-run Imprime o que a sessão seria e não inicia nada: o momento e o fuso resolvidos e de onde vieram, com o que um cenário preencheu cada parâmetro, os argumentos depois da divisão e qual dos dois mecanismos o alvo usaria. Nenhum processo é iniciado e nenhum arquivo é gravado, inclusive o que --report nomeia. Sai com 0 para um plano viável e com 2 para um alvo que não existe, que é o código que uma execução real dá para o mesmo fato. Um plano não traz veredito e diz isso - só uma sessão real tem um. Com --json o plano sai como dados, incluindo session.elevated_embedded e session.elevated_embedded_value, o nome de arquivo que daria nome ao valor do Registro quando a opção se aplica a um alvo .exe, e null caso contrário. Um nome ali não é promessa de gravação: a sessão só grava o valor quando o próprio Chrono Mock roda como administrador.
--report <path> Grava o relatório para pessoas em um arquivo. Um veredito diferente de funciona abre esse arquivo com um aviso de evidência não confiável, porque uma evidência que esconde a própria dúvida é pior que nenhuma. Uma sessão com veredito funciona também recebe esse aviso quando a aplicação não leu nenhum dos relógios que a sessão substitui, ou quando é um programa em Go, cujo relógio de parede o Chrono Mock não alcança. O arquivo também nomeia a própria execução: a versão, quando começou, o alvo, a pasta dele e as opções.
--report-args Junto com --report, grava também os argumentos do alvo nesse arquivo, palavra por palavra. Desligado por padrão, porque um argumento pode conter uma senha - o arquivo diz então só quantos eram.
--json Emite a sessão como registros legíveis por máquina em vez do relatório - o mesmo fluxo que a própria janela consome. A saída própria de um aplicativo de console vai para o erro padrão, então a saída padrão contém os registros e nada mais. Um aplicativo ainda em execução quando a sessão termina continua escrevendo ali, de modo que tudo o que lê o erro padrão até o fim espera por ele, e a execução avisa isso.

chrono run - códigos de saída

O código de saída é o veredito da sessão, não o que o aplicativo retornou. O código de saída do próprio aplicativo é informado à parte, no relatório e nos dados da sessão - a página CLI e CI explica por que é assim.

CódigoSignificado
0funciona - todo processo que leu a hora viu o relógio da sessão
10funciona parcialmente - alguns canais cobertos, outros não
11não funciona - a substituição não chegou aos canais principais
4indeterminado - não foi possível estabelecer a cobertura. Um honesto “não sei dizer”, nunca um sucesso fingido
12o alvo desapareceu logo após a injeção sem deixar nada rodando no relógio da sessão, o que sugere um aplicativo de instância única passando o controle a uma cópia já em execução, ou uma passagem para um programa em que a sessão não conseguiu entrar, em geral o da outra arquitetura (32/64 bits). Um alvo que inicia o aplicativo e termina é um inicializador, e a sessão continua para o aplicativo
1erro de uso - uma opção incorreta, uma expressão incorreta ou um cenário que este comando não aceita
2o alvo não pôde ser iniciado nem injetado
3erro interno - o motor não conseguiu iniciar, chegou a um estado inesperado ou parou antes de encerrar a sessão (qualquer que fosse o seu próprio código de saída). Uma execução assim não traz veredito
5a operação não está incluída nesta versão - por exemplo, um cenário cujo momento precisa de um calendário que o run ainda não consegue carregar. Deliberadamente distinto de um erro de uso: você pediu algo que ainda não existe, não algo errado
6a execução foi interrompida - --timeout expirou, ou o motor parou de responder por 15 segundos e foi parado. Isto não é um veredito: a sessão foi interrompida, então não prova nada sobre o alvo, em nenhum dos sentidos
7outra sessão já está em execução - uma sessão por vez. Basta tentar de novo quando ela terminar
8a sessão chegou a um veredito, mas a evidência não está no arquivo indicado por --report - o disco estava cheio, ou outro programa mantinha o arquivo antigo aberto, que então fica como estava. O veredito continua no relatório que o comando exibe

Como ler o relatório

Sem --json, a sessão termina em um relatório em texto simples. Cada linha é um fato que a sessão observou ou está ausente - nada é preenchido com um valor padrão plausível.

Chrono Mock - session report
  target:   .\build\test.exe
  verdict:  WORKS - time substitution took effect  (processes: 1)
            every process that read time saw the session clock
  session:  fake clock reached 2038-01-19T03:14:08
            real elapsed 1.3s, fake elapsed 1.3s
  exited:   the target closed itself with code 3
  covered channels (substituted, with call counts, 10 calls in all):
            - pid 21240: GetSystemTimeAsFileTime (5 calls)
            - pid 21240: GetLocalTime (5 calls)
  observed channels (hooked but left real):
            - pid 21240: NtCreateUserProcess (0 calls)
  warnings:
            - the target opened a network connection ...
  • verdict - o veredito da família sobre o processo pai e todo processo filho, com a contagem de processos. É o número que o código de saída carrega.
  • exited - o código de saída próprio do aplicativo, e somente quando ele se fechou sozinho. Uma execução limitada por --ticks deixa o alvo rodando, uma sessão Chromium é uma que a própria ferramenta fecha, e uma sessão que nunca iniciou não tem esse código - a linha fica então ausente em vez de mostrar um zero inventado. Um código de falha chega como um número negativo grande, então também recebe a forma hexadecimal.
  • covered - canais que a substituição alcançou, com quantas vezes cada um foi realmente chamado, por processo. As contagens nunca são somadas entre processos: a auditoria de um processo não deve tomar emprestados os números de outro. Um contador para em 1048576 e então indica pelo menos esse número.
  • observed - canais interceptados, mas deliberadamente deixados reais, como as esperas de objetos e os temporizadores multimídia. Uma categoria própria, para que nunca sejam lidos como substituídos.
  • uncovered - canais que o aplicativo pediu e que a sessão não cobriu. É o que transforma um veredito em parcialmente.
  • not fully cleaned up - tudo o que a limpeza não conseguiu remover. Ausente em um fim limpo, que é o caso normal.

chrono calc - opções

Sem linguagem natural: cada opção é um passo, e a ordem das opções é a ordem dos passos. O resultado depois de cada passo é impresso, então um passo errado fica visível em vez de enterrado.

OpçãoO que faz
--base today|now|<moment> Onde começar, today por padrão. Resolvido no fuso da sessão. Um dia impossível como 2025-02-31 é recusado, nunca normalizado em silêncio para o mês seguinte.
--base-utc <moment> Como --base, mas o início é um instante em UTC, com um Z final opcional, e não uma leitura de relógio de parede no fuso da sessão.
--shift ±N<unit> Repetível. O sinal é obrigatório. Unidades: s m h d w mo q y bd, ou seus nomes completos. m é minuto, mo é mês. Meses, trimestres e anos se dobram sobre a data do calendário com um limite, de modo que um mês depois de 31 de janeiro é o fim de fevereiro, e não um número fixo de ticks. bd (dias úteis) exige --calendar.
--set-time HH:MM:SSDefine a hora do dia no resultado atual.
--snap <target> Salta para um limite de período: som eom soq eoq soy eoy (início ou fim de mês, trimestre, ano). Um início é o primeiro dia às 00:00:00, um fim o último dia às 23:59:59.
--nearest nbd|pbd O dia útil mais próximo para frente ou para trás, incluindo o dia atual quando ele já é um. Exige --calendar.
--to-zone +HH:MM Um passo: reexpressa o mesmo instante em outro deslocamento fixo. O instante é preservado, então o valor epoch não se move e só os campos civis mudam. Não confundir com --zone.
--zone +HH:MM O fuso da sessão, usado para resolver today e now e para exibir o resultado. Sem ela, o fuso do host.
--calendar us-banking|us-federal|pl Carrega um calendário de feriados. Ele acrescenta dia útil e feriado aos metadados e habilita bd e --nearest. Os dois calendários americanos diferem na forma como observam um feriado que cai no fim de semana, que é exatamente o tipo de erro de um dia que um teste deve encontrar. Cada calendário responde por uma faixa de anos: pl a partir de 2002, us-federal a partir de 1960 e us-banking a partir de 2008. Um passo de dias úteis que chegue a um dia anterior é recusado com o código 1, e uma data anterior é mostrada como não julgada. Quando os feriados de um calendário foram conferidos com a lei há mais de um ano, um dia posterior que ele julgou recebe a marca calendar_outdated, porque pode faltar um feriado mais recente.
--preset <id> --param id=value Um momento nomeado de presets/<id>.json, com seus parâmetros preenchidos. Exclusivo com as opções de passo e com --analyze, e se combina com --calendar, --zone e --format.
--analyze <date> Lê de volta uma data colada e diz o que ela é. Um 04/08 ambíguo é mostrado nas duas leituras, americana e polonesa, em vez de adivinhado - essa ambiguidade é uma fonte real de relatórios de bug equivocados.
--format <mask> Imprime também o resultado na sua própria máscara, para que combine com o formato do aplicativo testado: yyyy-MM-dd HH:mm:ss. Os tokens diferenciam maiúsculas de minúsculas ao estilo do .NET e do Java - M é mês, m é minuto.
--json Saída para máquinas (chronomock.calc/1) para qualquer um dos acima, de modo que um pipeline possa calcular uma data e devolvê-la direto ao chrono run.
# Último dia útil do trimestre, calendário bancário americano
chrono calc --base today --snap eoq --nearest pbd --calendar us-banking

chrono calc - códigos de saída

Uma tabela separada e menor: a calculadora não tem um veredito de cobertura para relatar.

CódigoSignificado
0calculado
1erro de uso - uma opção incorreta, uma data impossível, um estouro de intervalo ou um arquivo de calendário sem nenhum dia útil
5o passo ou a unidade não está incluído nesta versão, ou o passo precisa de um calendário que você não passou. Separado de um erro de uso de propósito, para que um script distinga “ainda não” de “errado”

Próximo