This test ensures a link is still clicked when it is covered by another element, but is uncovered before the timout expires. This is a common pattern where AJAX is involved, when a loading spinner covers a clickable element until the AJAX request has finished.

!define HTML { {{{

	The Link

}}} }

!*> Mock server

|script      |mock xml server setup|
|add response|${HTML}              |
|add response|${HTML}              |
|$url=       |get mock server url  |

*!

|script                |browser test|
|open                  |$url        |
|seconds before timeout|4           |
|click                 |The Link    |

|script|mock xml server setup|
|stop                        |

Add test to ensure 'click if available' returns false for not-clickable element

This test ensures a link is still clicked when it is covered by another element, but is uncovered before the timout expires. This is a common pattern where AJAX is involved, when a loading spinner covers a clickable element until the AJAX request has finished.

!define HTML { {{{

	The Link

}}} }

!*> Mock server

|script      |mock xml server setup|
|add response|${HTML}              |
|add response|${HTML}              |
|$url=       |get mock server url  |

*!

|script                |browser test               |
|open                  |$url                       |
|seconds before timeout|1                          |
|reject                |click if available|The Link|
|seconds before timeout|4                          |
|click                 |The Link                   |

|script|mock xml server setup|
|stop                        |


This test shows some manipulation of the browser window.

|storyboard         |browser test                      |
|$width1=           |current browser width             |
|$height1=          |current browser height            |
|open               |http://stackoverflow.com          |
|scroll to          |recent questions feed             |
|set browser width  |420                               |
|check              |current browser width |420        |
|check              |current browser height|$height1   |
|set browser height |600                               |
|check              |current browser width |420        |
|check              |current browser height|600        |
|set browser size to|$width1               |by|$height1|
|check              |current browser width |$width1    |
|check              |current browser height|$height1   |
|set browser size to maximum                           |
|show               |current browser width             |
|show               |current browser height            |

Use a bit wider screen

This test shows some manipulation of the browser window.

|storyboard         |browser test                      |
|$width1=           |current browser width             |
|$height1=          |current browser height            |
|open               |http://stackoverflow.com          |
|scroll to          |recent questions feed             |
|set browser width  |495                               |
|check              |current browser width |495        |
|check              |current browser height|$height1   |
|set browser height |600                               |
|check              |current browser width |495        |
|check              |current browser height|600        |
|set browser size to|$width1               |by|$height1|
|check              |current browser width |$width1    |
|check              |current browser height|$height1   |
|set browser size to maximum                           |
|show               |current browser width             |
|show               |current browser height            |


This test shows some manipulation of the browser window.

|storyboard         |browser test                      |
|$width1=           |current browser width             |
|$height1=          |current browser height            |
|open               |http://stackoverflow.com          |
|scroll to          |recent questions feed             |
|set browser width  |400                               |
|check              |current browser width |400        |
|check              |current browser height|$height1   |
|set browser height |600                               |
|check              |current browser width |400        |
|check              |current browser height|600        |
|set browser size to|$width1               |by|$height1|
|check              |current browser width |$width1    |
|check              |current browser height|$height1   |
|set browser size to maximum                           |
|show               |current browser width             |
|show               |current browser height            |

Use width supported on travis

This test shows some manipulation of the browser window.

|storyboard         |browser test                      |
|$width1=           |current browser width             |
|$height1=          |current browser height            |
|open               |http://stackoverflow.com          |
|scroll to          |recent questions feed             |
|set browser width  |420                               |
|check              |current browser width |420        |
|check              |current browser height|$height1   |
|set browser height |600                               |
|check              |current browser width |420        |
|check              |current browser height|600        |
|set browser size to|$width1               |by|$height1|
|check              |current browser width |$width1    |
|check              |current browser height|$height1   |
|set browser size to maximum                           |
|show               |current browser width             |
|show               |current browser height            |


---
Help: Test support for RichFaces Ajax (disabled because Richfaces showcase site is too unreliable/slow)
Prune
---
Unfortunately we can't check with local server (since we don't want to set up all javascript dependencies).
We ensure we can properly wait for richfaces ajax to render elements.

|script                |rich faces test                                                                                |
|open                  |http://showcase.richfaces.org/richfaces/component-sample.jsf?demo=ajax&sample=selectsUpdates&skin=classic|
|seconds before timeout|2                                                                                |
|select                |Fruits                               |for                      |xpath=(//select)[1]                      |
|select                |Banana                               |for                      |xpath=(//select)[2]                      |
|show                  |take screenshot                      |rf                                                                 |

Switch RichFaces test to page that actually responds

---
Help: Test support for RichFaces Ajax (disabled because Richfaces showcase site is too unreliable/slow)
---
Unfortunately we can't check with local server (since we don't want to set up all javascript dependencies).
We ensure we can properly wait for richfaces ajax to render elements.

|script                |rich faces test                                                                                |
|open                  |https://www.triodos.nl/nl/particulieren/sparen/spaarrekening-voor-mezelf/maand-sparen/form-opening-maandsparen/|
|click                 |Vul uw gegevens in                                                                                |
|seconds before timeout|2                                                                                |
|enter                 |f                        |as                                        |xpath=(//input[@type='text'])[2]          |
|check                 |value of                 |xpath=(//input[@type='text'])[2]          |F.                                        |
|enter                 |fitnesse                 |as                                        |xpath=(//input[@type='text'])[3]          |
|check                 |value of                 |xpath=(//input[@type='text'])[3]          |Fitnesse                                  |
|show                  |take screenshot          |rf                                                                                |


#summary notes from releases

= Release Notes =

== 1.0.1 ==

 * lowercase ipv6 addresses (http://codereview.appspot.com/7678)

Expand release notes; add note of repr() change. Other changes are cleanups, not visible.

#summary notes from releases

= Release Notes =

Here are the visible changes for each release.

== 1.0.1 ==

  * str() now produces lowercase for IPv6 addresses, to match inet_pton(3). (http://codereview.appspot.com/7678)
  * repr() now produces strings that can be pasted back into the interpreter.


This test ensures we can deal with file upload inputs.

!define HTML { {{{
<html>
<body>
Choose file:
<input name="chosenFile" type="file">
<input name="chosenFile2" type="file">
<button>Upload</button>
</body>
</html>}}} }

|script      |mock xml server setup|
|add response|${HTML}              |
|$url=       |get mock server url  |

|script     |file fixture                        |
|$generated=|create|bye1.txt|containing|Bye Bye 1|

|script     |browser test                                |
|open       |$url                                        |
|note       |Select file for first file upload on page   |
|select file|$generated                                  |
|check      |value of  |name=chosenFile |=~/bye1.txt/    |
|check      |value of  |name=chosenFile2|!--!            |
|note       |Select file for specific file upload on page|
|select file|$generated|for             |name=chosenFile2|
|check      |value of  |name=chosenFile |=~/bye1.txt/    |
|check      |value of  |name=chosenFile2|=~/bye1.txt/    |

|script|mock xml server setup|
|stop                        |

Downgrade to latest phantomjs driver from codeborn, see whether that supports Java 7

---
Help: Skipped because PhantomJs on Linux seems to crash when using file inputs.
Prune
---
This test ensures we can deal with file upload inputs.

!define HTML { {{{
<html>
<body>
Choose file:
<input name="chosenFile" type="file">
<input name="chosenFile2" type="file">
<button>Upload</button>
</body>
</html>}}} }

|script      |mock xml server setup|
|add response|${HTML}              |
|$url=       |get mock server url  |

|script     |file fixture                        |
|$generated=|create|bye1.txt|containing|Bye Bye 1|

|script     |browser test                                |
|open       |$url                                        |
|note       |Select file for first file upload on page   |
|select file|$generated                                  |
|check      |value of  |name=chosenFile |=~/bye1.txt/    |
|check      |value of  |name=chosenFile2|!--!            |
|note       |Select file for specific file upload on page|
|select file|$generated|for             |name=chosenFile2|
|check      |value of  |name=chosenFile |=~/bye1.txt/    |
|check      |value of  |name=chosenFile2|=~/bye1.txt/    |

|script|mock xml server setup|
|stop                        |


Ocsigen start is still alpha.
Look at the API documentaion for more information.

Add some text to manual

=Introduction=

Ocsigen Start is the fastest way to get started with Ocsigen. It
consists of a library and an associated application template that
combined implement standard functionality like users and
notifications. The programmer can thus focus on the specificities of
their application domain and quickly obtain a Minimum Viable Product
(MVP).

Ocsigen Start is built on Eliom. Eliom focuses on the core machinery,
while Ocsigen Start provides higher-level concepts that require a
database and certain design decisions.

Ocsigen Start is mobile-friendly. The template application readily
works as an Android and iOS application (via
[[https://cordova.apache.org/|Cordova]]).

==Implementation overview==

===Template===

The library portion of Ocsigen Start contains core functionality that
is common across Ocsigen Start applications, while the template can be
customized for the specific application at hand.

The template additionally contains a demonstration of relevant
[[Ocsigen Toolkit|https://github.com/ocsigen/ocsigen-toolkit]]
widgets. The demo portion can easily be removed.

===Database===

For implementing users, a database is needed. Specifically, we use
[[PostgreSQL|https://www.postgresql.org/]] via the
[[PG'OCaml|http://pgocaml.forge.ocamlcore.org/]] library. The template
and the library make common assumptions about the database schema. The
database thus needs to be instantiated in a certain way; this is
automatically done by appropriate targets in the template's build
system. The database can be

===Managing e-mails===

The template application keeps track of users' e-mails and implements
e-mail validation. For that, {{{sendmail}}} (or another mail transfer
agent compatible with it) needs to be installed on the host.

===Style===

The application provides a standard style matching contemporary
aesthetics. For this, we use [[SASS|http://sass-lang.com/]]. The style
can be customized by modifying the SASS files that are part of the
template.

==Installation==

Ocsigen Start can be installed via
[[OPAM|https://opam.ocaml.org/]]. The package name
{{{ocsigen-start}}}. The template application can be instantiated via
{{{eliom-distillery}}}:

<<code language="shell"|
eliom-distillery -name $APP_NAME -template os.pgocaml
>>

For details on launching the application, refer to the template's
[[README|https://github.com/ocsigen/ocsigen-start/blob/master/template.distillery/README.md]].


---
Suite
---
!1 Test suite X
!contents -R2 -g -p -f -h

|Import                           |
|nl.hsac.fitnesse.fixture         |
|nl.hsac.fitnesse.fixture.slim    |

Simplify setup page for tagged test cases

---
Static
---
|Import                       |
|nl.hsac.fitnesse.fixture     |
|nl.hsac.fitnesse.fixture.slim|


---
Test
Help: Test support for RichFaces Ajax
---

Unfortunately we can't check with local server (since we don't want to set up all javascript dependencies).
We ensure we can properly wait for richfaces ajax to render elements.

|script                |rich faces test                                                                                |
|open                  |http://showcase.richfaces.org/richfaces/component-sample.jsf?demo=ajax&sample=selectsUpdates&skin=classic|
|seconds before timeout|2                                                                                |
|select                |Fruits         |for|id=form:j_idt1906                                                                    |
|select                |Banana         |for|name=form:j_idt1908                                                                  |
|show                  |take screenshot|rf                                                                                |

Make test robust to id/name changes

---
Help: Test support for RichFaces Ajax
---
Unfortunately we can't check with local server (since we don't want to set up all javascript dependencies).
We ensure we can properly wait for richfaces ajax to render elements.

|script                |rich faces test                                                                                |
|open                  |http://showcase.richfaces.org/richfaces/component-sample.jsf?demo=ajax&sample=selectsUpdates&skin=classic|
|seconds before timeout|2                                                                                |
|select                |Fruits                               |for                      |xpath=(//select)[1]                      |
|select                |Banana                               |for                      |xpath=(//select)[2]                      |
|show                  |take screenshot                      |rf                                                                 |


Available in [BlazeMeterSet BlazeMeter Set]

= Weighted Switch Controller since 1.4.0=

== Authorship ==

[http://blazemeter.com/?utm_source=jmplinnerpages&utm_medium=cpc&utm_content=jmpininnerpgs&utm_campaign=JMeter%2BPlug%2BIn%2BWiki https://d3qmoqvtroy6p7.cloudfront.net/logo.png]

This plugin was originally developed by _[http://blazemeter.com/?utm_source=jmplinnerpages&utm_medium=cpc&utm_content=jmpininnerpgs&utm_campaign=JMeter%2BPlug%2BIn%2BWiki BlazeMeter Inc.]_ and then generously donated to community as Open Source.
Check out their [http://blazemeter.com/?utm_source=jmplinnerpages&utm_medium=cpc&utm_content=jmpininnerpgs&utm_campaign=JMeter%2BPlug%2BIn%2BWiki load testing service],
there's a lot of value to load testing people.

== Description ==

This controller takes the information about child elements and offers managing relative weights for them. Relative weight means how frequently the child element will be executed during thread iterations. Please note that each thread has independent counter of iterations.

[/img/wiki/WeightedSwitchController.png]

Remove blazemeter set from docs

Available in [StandardSet Standard Set]

= Weighted Switch Controller since 1.4.0=

== Authorship ==

[http://blazemeter.com/?utm_source=jmplinnerpages&utm_medium=cpc&utm_content=jmpininnerpgs&utm_campaign=JMeter%2BPlug%2BIn%2BWiki https://d3qmoqvtroy6p7.cloudfront.net/logo.png]

This plugin was originally developed by _[http://blazemeter.com/?utm_source=jmplinnerpages&utm_medium=cpc&utm_content=jmpininnerpgs&utm_campaign=JMeter%2BPlug%2BIn%2BWiki BlazeMeter Inc.]_ and then generously donated to community as Open Source.
Check out their [http://blazemeter.com/?utm_source=jmplinnerpages&utm_medium=cpc&utm_content=jmpininnerpgs&utm_campaign=JMeter%2BPlug%2BIn%2BWiki load testing service],
there's a lot of value to load testing people.

== Description ==

This controller takes the information about child elements and offers managing relative weights for them. Relative weight means how frequently the child element will be executed during thread iterations. Please note that each thread has independent counter of iterations.

[/img/wiki/WeightedSwitchController.png]


= Deserialize php serialized strings in java =

This nice class deserialize a php serialized string in java.

is original from [http://code.google.com/p/serialized-php-parser/]

Change from mdeiawiki to md

# Deserialize php serialized strings in java

This nice class deserialize a php serialized string in java.

This is a fork from [Google Code Serialized Php Parser](http://code.google.com/p/serialized-php-parser/)


= Extras Set =
Additional plugins for extended and complex testing. Does not require additional libs to run.

== Graphs ==
  * [ResponseCodesPerSecond Response Codes per Second]
  * [LatenciesOverTime Response Latencies Over Time]
  * [BytesThroughput Bytes Throughput Over Time]
  * [PageDataExtractor Extracted Data Over Time]
  * [DbMon DbMon Sample Collector]
  * [JMXMon JMX Monitoring Collector]
  * [ResponseTimesVsThreads Response Times vs Threads]
  * [TransactionThroughputVsThreads Transaction Throughput vs Threads]
  * [RespTimesDistribution Response Times Distribution]
  * [RespTimePercentiles Response Times Percentiles]

== Listeners ==
  * [AutoStop] Trigger

== Samplers ==
  * [UDPRequest UDP Sampler]
  * [RawRequest HTTP Raw Request]

== Others ==
  * [VariablesFromCSV Variables from CSV] configuration item
  * [ParameterizedController Parameterized Controller] to re-use test plan modules
  * [RawDataSource Raw Data Source]
  * [XMLFormatPostProcessor XML Format PostProcessor]
  * [LockFile Lock Files]

Add docs reference in Extras and Start

= Extras Set =
Additional plugins for extended and complex testing. Does not require additional libs to run.

== Graphs ==
  * [ResponseCodesPerSecond Response Codes per Second]
  * [LatenciesOverTime Response Latencies Over Time]
  * [BytesThroughput Bytes Throughput Over Time]
  * [PageDataExtractor Extracted Data Over Time]
  * [DbMon DbMon Sample Collector]
  * [JMXMon JMX Monitoring Collector]
  * [ResponseTimesVsThreads Response Times vs Threads]
  * [TransactionThroughputVsThreads Transaction Throughput vs Threads]
  * [RespTimesDistribution Response Times Distribution]
  * [RespTimePercentiles Response Times Percentiles]

== Listeners ==
  * [AutoStop] Trigger
  * [GraphsGeneratorListener] Graphs Generator

== Samplers ==
  * [UDPRequest UDP Sampler]
  * [RawRequest HTTP Raw Request]

== Others ==
  * [VariablesFromCSV Variables from CSV] configuration item
  * [ParameterizedController Parameterized Controller] to re-use test plan modules
  * [RawDataSource Raw Data Source]
  * [XMLFormatPostProcessor XML Format PostProcessor]
  * [LockFile Lock Files]


Update readme and test MediaWiki support.

[[File:web_hi_res_512.png]]

=== License ===

Copyright 2015 Stephen Niedzielski

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


= Js_of_ocaml =

Js_of_ocaml is a compiler of OCaml bytecode to Javascript.  It makes it possible to run Ocaml programs in a Web browser.  Its key features are the following:
* The whole language, and most of the standard library are supported.
* The compiler is easy to install: it only depends on [[http://projects.camlcity.org/projects/findlib.html|Findlib]] and [[wiki(21):|Lwt]].
* The generated code is independant of [[wiki(15):|Eliom]] and the [[wiki(12):|Ocsigen server]]. You can use it with any Web server.
* You can use a standard installation of OCaml to compile your programs.  In particular, you do not have to recompile a library to use it with Js_of_ocaml.
You just have to link your program with a specific library to interface with the browser APIs.

A few small demos are available on-line:
* [[planet|An animated 3D view of the Earth]]
* [[graph|A graph viewer]]
* [[boulderdash|A Boulder Dash game]]
* [[wiki|A realtime wiki editor]]

You can also read a more detailed [[overview|overview]] with installation instructions and the [[lib/overview|documentation of the associated library]].

Add the toplevel to Ocsigen website

= Js_of_ocaml =

Js_of_ocaml is a compiler of OCaml bytecode to Javascript.  It makes it possible to run Ocaml programs in a Web browser.  Its key features are the following:
* The whole language, and most of the standard library are supported.
* The compiler is easy to install: it only depends on [[http://projects.camlcity.org/projects/findlib.html|Findlib]] and [[wiki(21):|Lwt]].
* The generated code is independant of [[wiki(15):|Eliom]] and the [[wiki(12):|Ocsigen server]]. You can use it with any Web server.
* You can use a standard installation of OCaml to compile your programs.  In particular, you do not have to recompile a library to use it with Js_of_ocaml.
You just have to link your program with a specific library to interface with the browser APIs.

A few small demos are available on-line:
* [[toplevel|An OCaml toplevel running in the browser]
* [[planet|An animated 3D view of the Earth]]
* [[graph|A graph viewer]]
* [[boulderdash|A Boulder Dash game]]
* [[wiki|A realtime wiki editor]]

You can also read a more detailed [[overview|overview]] with installation instructions and the [[lib/overview|documentation of the associated library]].


= Test page =

== Lists ==
* Test links [http://www.google.fi Google]
* Foo
** Nested under Foo
** Still nested under Foo
* Top-level

* TodoListForNwiki
** Foobar
** Barfoo
*** sdf
* Hoax
* Poax

One item:
* List

Two items:
* Item 1
* Item 2

Three items, one nested
* Item 1
* Item 2
** Nested Item 1

Four items, one nested
* Item 1
* Item 2
** Nested Item 1
* Item 3

<pre>
foo

</pre>

== Paragraphs of text ==

Paragraphs of text.  Paragraphs: My habanero started to flower a few weeks ago, and now, November 1st, it has produced a couple of pods as well. Quite surprising given the amount of light we have.

Paragraphs of text.  Paragraphs: My habanero started to flower a few weeks ago, and now, November 1st, it has produced a couple of pods as well. Quite surprising given the amount of light we have.

Update Nurpawiki test page to cover more link tests

= Test page =

== Lists ==
* Test links [http://www.google.fi Google] and [http://www.google.fi]
** Nested under Foo
** Still nested under Foo
* Top-level

* TodoListForNwiki
** Foobar
** Barfoo
*** sdf
* Hoax
* Poax

One item:
* List

Two items:
* Item 1
* Item 2

Three items, one nested
* Item 1
* Item 2
** Nested Item 1

Four items, one nested
* Item 1
* Item 2
** Nested Item 1
* Item 3

<pre>
foo

</pre>

== Paragraphs of text ==

Paragraphs of text.  Paragraphs: My habanero started to flower a few weeks ago, and now, November 1st, it has produced a couple of pods as well. Quite surprising given the amount of light we have.

Paragraphs of text.  Paragraphs: My habanero started to flower a few weeks ago, and now, November 1st, it has produced a couple of pods as well. Quite surprising given the amount of light we have.


---
Help: Test support for RichFaces Ajax (disabled because Richfaces showcase site is too unreliable/slow)
---
Unfortunately we can't check with local server (since we don't want to set up all javascript dependencies).
We ensure we can properly wait for richfaces ajax to render elements.

|script                |rich faces test                                                                                |
|open                  |https://www.triodos.nl/nl/particulieren/sparen/spaarrekening-voor-mezelf/maand-sparen/form-opening-maandsparen/|
|click                 |Vul uw gegevens in                                                                                |
|seconds before timeout|2                                                                                |
|enter                 |f                        |as                                        |xpath=(//input[@type='text'])[2]          |
|check                 |value of                 |xpath=(//input[@type='text'])[2]          |F.                                        |
|enter                 |fitnesse                 |as                                        |xpath=(//input[@type='text'])[3]          |
|check                 |value of                 |xpath=(//input[@type='text'])[3]          |Fitnesse                                  |
|show                  |take screenshot          |rf                                                                                |

Update help text to no longer state test is skipped/disabled

---
Help: Test support for RichFaces Ajax
---
Unfortunately we can't check with local server (since we don't want to set up all javascript dependencies).
We ensure we can properly wait for richfaces ajax to render elements.

|script                |rich faces test                                                                                |
|open                  |https://www.triodos.nl/nl/particulieren/sparen/spaarrekening-voor-mezelf/maand-sparen/form-opening-maandsparen/|
|click                 |Vul uw gegevens in                                                                                |
|seconds before timeout|2                                                                                |
|enter                 |f                        |as                                        |xpath=(//input[@type='text'])[2]          |
|check                 |value of                 |xpath=(//input[@type='text'])[2]          |F.                                        |
|enter                 |fitnesse                 |as                                        |xpath=(//input[@type='text'])[3]          |
|check                 |value of                 |xpath=(//input[@type='text'])[3]          |Fitnesse                                  |
|show                  |take screenshot          |rf                                                                                |


= Extras Set =
Additional plugins for extended and complex testing. Does not require additional libs to run.

== Graphs ==
  * [ResponseCodesPerSecond Response Codes per Second]
  * [LatenciesOverTime Response Latencies Over Time]
  * [BytesThroughput Bytes Throughput Over Time]
  * [PageDataExtractor Extracted Data Over Time]
  * [DbMon DbMon Sample Collector]
  * [ResponseTimesVsThreads Response Times vs Threads]
  * [TransactionThroughputVsThreads Transaction Throughput vs Threads]
  * [RespTimesDistribution Response Times Distribution]
  * [RespTimePercentiles Response Times Percentiles]

== Listeners ==
  * [AutoStop] Trigger

== Samplers ==
  * [UDPRequest UDP Sampler]
  * [RawRequest HTTP Raw Request]

== Others ==
  * [VariablesFromCSV Variables from CSV] configuration item
  * [ParameterizedController Parameterized Controller] to re-use test plan modules
  * [RawDataSource Raw Data Source]
  * [XMLFormatPostProcessor XML Format PostProcessor]
  * [LockFile Lock Files]

Add link to JMX Mon

= Extras Set =
Additional plugins for extended and complex testing. Does not require additional libs to run.

== Graphs ==
  * [ResponseCodesPerSecond Response Codes per Second]
  * [LatenciesOverTime Response Latencies Over Time]
  * [BytesThroughput Bytes Throughput Over Time]
  * [PageDataExtractor Extracted Data Over Time]
  * [DbMon DbMon Sample Collector]
  * [JMXMon JMX Monitoring Collector]
  * [ResponseTimesVsThreads Response Times vs Threads]
  * [TransactionThroughputVsThreads Transaction Throughput vs Threads]
  * [RespTimesDistribution Response Times Distribution]
  * [RespTimePercentiles Response Times Percentiles]

== Listeners ==
  * [AutoStop] Trigger

== Samplers ==
  * [UDPRequest UDP Sampler]
  * [RawRequest HTTP Raw Request]

== Others ==
  * [VariablesFromCSV Variables from CSV] configuration item
  * [ParameterizedController Parameterized Controller] to re-use test plan modules
  * [RawDataSource Raw Data Source]
  * [XMLFormatPostProcessor XML Format PostProcessor]
  * [LockFile Lock Files]


= Standard Set =
Basic plugins for everyday needs. Does not require additional libs to run.

== Graphs ==
  * [PerfMon PerfMon Metrics Collector] and [PerfMonAgent Server Agent]
  * [ActiveThreadsOverTime Active Threads Over Time]
  * [ResponseTimesOverTime Response Times Over Time]
  * [TransactionsPerSecond Transactions per Second]
  * [HitsPerSecond Server Hits per Seconds]
  * [CompositeGraph Composite Timeline Graph]

== Thread Groups & Timers ==
  * [SteppingThreadGroup Stepping Thread Group]
  * [UltimateThreadGroup Ultimate Thread Group]
  * [ThroughputShapingTimer Throughput Shaping Timer]
  * [ConcurrencyThreadGroup Concurrency Thread Group]
  * [ArrivalsThreadGroup Arrivals Thread Group]
  * [FreeFormArrivalsThreadGroup Free-Form Arrivals Thread Group]

== Listeners ==
  * [FlexibleFileWriter Flexible File Writer]
  * [ConsoleStatusLogger Non-GUI Console Status Logger]
  * [LoadosophiaUploader BM.Sense Uploader] (aka Loadosophia Uploader)

== Others ==
  * [JMeterPluginsCMD Command-Line Graph Plotting Tool]
  * [InterThreadCommunication Inter-Thread Communication]
  * [Functions Custom JMeter Functions]
  * [TestPlanCheckTool Command-Line Test Plan Consistency Checking Tool]
  * [FilterResultsTool Command-Line filtered results] by label (regex), offset, success
  * [WeightedSwitchController Weighted Switch Controler]

== Samplers ==
  * [DummySampler Dummy Sampler] for debugging and programming tests

Add Synthesis Report in the Listeners list

= Standard Set =
Basic plugins for everyday needs. Does not require additional libs to run.

== Graphs ==
  * [PerfMon PerfMon Metrics Collector] and [PerfMonAgent Server Agent]
  * [ActiveThreadsOverTime Active Threads Over Time]
  * [ResponseTimesOverTime Response Times Over Time]
  * [TransactionsPerSecond Transactions per Second]
  * [HitsPerSecond Server Hits per Seconds]
  * [CompositeGraph Composite Timeline Graph]

== Thread Groups & Timers ==
  * [SteppingThreadGroup Stepping Thread Group]
  * [UltimateThreadGroup Ultimate Thread Group]
  * [ThroughputShapingTimer Throughput Shaping Timer]
  * [ConcurrencyThreadGroup Concurrency Thread Group]
  * [ArrivalsThreadGroup Arrivals Thread Group]
  * [FreeFormArrivalsThreadGroup Free-Form Arrivals Thread Group]

== Listeners ==
  * [FlexibleFileWriter Flexible File Writer]
  * [ConsoleStatusLogger Non-GUI Console Status Logger]
  * [LoadosophiaUploader BM.Sense Uploader] (aka Loadosophia Uploader)
  * [SynthesisReport Synthesis Report] filterable by label (regex), offset

== Others ==
  * [JMeterPluginsCMD Command-Line Graph Plotting Tool]
  * [InterThreadCommunication Inter-Thread Communication]
  * [Functions Custom JMeter Functions]
  * [TestPlanCheckTool Command-Line Test Plan Consistency Checking Tool]
  * [FilterResultsTool Command-Line filtered results] by label (regex), offset, success
  * [WeightedSwitchController Weighted Switch Controler]

== Samplers ==
  * [DummySampler Dummy Sampler] for debugging and programming tests


[/img/icons/twitter-logo.gif]
[https://twitter.com/#!/jmeter_plugins Follow us on Twitter]

[/img/icons/chart-bar-icon.png]
[http://loadosophia.org/?utm_source=jpgc&utm_medium=link&utm_campaign=sidebar Analyze your test results online]

[/img/icons/donate_paypal.gif] *[/donations/ Support the project with donation]*

Add donate button to sidebar

[/img/icons/twitter-logo.gif]
[https://twitter.com/#!/jmeter_plugins Follow us on Twitter]

[/img/icons/chart-bar-icon.png]
[http://loadosophia.org/?utm_source=jpgc&utm_medium=link&utm_campaign=sidebar Analyze your test results online]

[/img/icons/donate_paypal.gif] *[/donations/ Support the project with donation]*

<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top" style="text-align: center; margin: 0; padding: 0">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="9PYQWYT4BGTHW">
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">

</form>


Documentation

  *  [scripting.wiki|Scripting]

Make the script manual link actually work.

Documentation

  *  [/doc/trunk/doc/scripting.wiki|Scripting]


The [[mw:Extension:PageViewInfo|PageViewInfo]] extension provides pageview data via
* action=info ([{{fullurl:Main Page|action=info}} example])

Add example links to the API options

The [[mw:Extension:PageViewInfo|PageViewInfo]] extension provides pageview data via
* action=info ([{{fullurl:Main Page|action=info}} example])
* API prop=pageviews ([{{fullurl:Special:ApiSandbox|#action=query&format=json&prop=pageviews&list=&titles=Main+Page}} example])
* API meta=siteviews ([{{fullurl:Special:ApiSandbox|#action=query&format=json&meta=siteviews}} example])
* API list=mostviewed ([{{fullurl:Special:ApiSandbox|#action=query&format=json&list=mostviewed&pvimlimit=50}} example], [{{fullurl:Special:ApiSandbox|#action=query&format=json&generator=mostviewed&gpvimlimit=10}} generator example])


---
Help: Http GET without following redirect
---
!define REDIRECT_URL {http://www.hotmail.com}

First we do a 'normal' GET to ${REDIRECT_URL}, which will redirect us.

|script  |http test          |
|get from|${REDIRECT_URL}    |
|check   |response status|200|
|show    |response headers   |

Then we do the same call without following the redirect, allowing us to inspect that a redirect is sent and what the redirect location is.

|script  |http test                                                      |
|get from|${REDIRECT_URL}|no redirect                                    |
|check   |response status|301                                            |
|check   |response header|Location|!-https://mail.live.com/default.aspx-!|
|show    |response                                                       |

Fix expected target of redirect test

---
Help: Http GET without following redirect
---
!define REDIRECT_URL {http://www.hotmail.com}

First we do a 'normal' GET to ${REDIRECT_URL}, which will redirect us.

|script  |http test          |
|get from|${REDIRECT_URL}    |
|check   |response status|200|
|show    |response headers   |

Then we do the same call without following the redirect, allowing us to inspect that a redirect is sent and what the redirect location is.

|script  |http test                                                 |
|get from|${REDIRECT_URL}|no redirect                               |
|check   |response status|301                                       |
|check   |response header|Location|!-https://outlook.live.com/owa/-!|
|show    |response                                                  |


{{if|authentified}
Variable authentified does not exist => this is not visible.

== Hidden header ==

{{else}}
This is the visible section

== Visible header ==

{{end}}


Add an acceptance test for clicking a temporarily covered link

This test ensures a link is still clicked when it is covered by another element, but is uncovered before the timout expires. This is a common pattern where AJAX is involved, when a loading spinner covers a clickable element until the AJAX request has finished.

!define HTML { {{{

	The Link

}}} }

!*> Mock server

|script      |mock xml server setup|
|add response|${HTML}              |
|add response|${HTML}              |
|$url=       |get mock server url  |

*!

|script                |browser test|
|open                  |$url        |
|seconds before timeout|4           |
|click                 |The Link    |

|script|mock xml server setup|
|stop                        |


Add test using 'define alias' to prevent all script table headers to require changes.

---
Help: Sample test using hsac-xebium-bridge, using script table header as for Xebiun
---

Normally a 'define alias' table would go in the suite setup, but here we do it locally.

|define alias                                        |
|selenium driver fixture|hsac selenium driver fixture|

|script       |selenium driver fixture                        |
|start browser|chrome|on url    |http://example.com/login     |
|ensure       |do    |verifyText|on|css=h1|with|Example Domain|
|stop browser                                                 |


Add temporary 'say' and 'print' global functions.

## $Id$

=head1 NAME

src/s1_setting.pir -  A few built-ins specific to Stage 1

=head1 DESCRIPTION

This file contains various subs and/or methods that we want to make
available to the Stage 1 compiler. Anything in this file is not included
in the final Rakudo PBC, just in the PBC for perl6_s1.pbc.

=cut

.namespace []

.sub 'say'
    .param pmc args :slurpy
    $S0 = join '', args
    say $S0
.end

.sub 'print'
    .param pmc args :slurpy
    $S0 = join '', args
    print $S0
.end

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:


# Copyright (C) 2009, Patrick R. Michaud
# $Id$

=head1 NAME

Regex::Cursor-builtins - builtin regexes for Cursor objects

=cut

.include 'cclass.pasm'

.namespace ['Regex';'Cursor']

.sub '!cclass' :method
    .param string name
    .param int cclass
    .local pmc cur
    .local int pos
    .local string tgt
    (cur, pos, tgt) = self.'!cursor_start'()
    $I0 = is_cclass cclass, tgt, pos
    unless $I0 goto fail
    inc pos
    cur.'!matchify'(name, 'pos'=>pos)
  fail:
    .return (cur)
.end

.sub 'alpha' :method
    .tailcall self.'!cclass'('alpha', .CCLASS_ALPHABETIC)
.end

.sub 'digit' :method
    .tailcall self.'!cclass'('digit', .CCLASS_NUMERIC)
.end

=head1 AUTHORS

Patrick Michaud <pmichaud@pobox.com> is the author and maintainer.

=cut

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:


.namespace [ "_Tcl" ]

=head2 _Tcl::__list

Given a PMC, get a list from it. If the PMC is a TclLst,
this is as simple as returning the list. If it's a string,
use __stringToList.

=cut

.sub __list
  .param pmc value

  $I0 = typeof value
  if $I0 == .TclList goto done

  $S0 = value
  .return __stringToList($S0)

done:
  .return(value)
.end

=head2 _Tcl::__number

Given a PMC, get a number from it.

=cut

.sub __number
  .param pmc value

  $I0 = typeof value
  if $I0 == .TclInt goto done
  if $I0 == .TclFloat goto done

  $S0 = value
  $I0 = length $S0

  .local int multiplier
  multiplier = 1

  $S1 = substr $S0, 0, 1
  # If the first character is -, assume a negative number.
  unless $S1 == "-" goto get_value
  multiplier = -1
  $I0 = length $S0
  dec $I0
  $S0 = substr $S0, 1, $I0
get_value:
  (value, $I1) = get_number($S0, 0)
  if_null value, NaN
  if $I0 != $I1 goto NaN
  value *= multiplier

done:
  .return(value)

NaN:
  .throw("Not a number!")
.end

Make __number() handle explicit + numbers

.namespace [ "_Tcl" ]

=head2 _Tcl::__list

Given a PMC, get a list from it. If the PMC is a TclLst,
this is as simple as returning the list. If it's a string,
use __stringToList.

=cut

.sub __list
  .param pmc value

  $I0 = typeof value
  if $I0 == .TclList goto done

  $S0 = value
  .return __stringToList($S0)

done:
  .return(value)
.end

=head2 _Tcl::__number

Given a PMC, get a number from it.

=cut

.sub __number
  .param pmc value

  $I0 = typeof value
  if $I0 == .TclInt goto done
  if $I0 == .TclFloat goto done

  $S0 = value
  $I0 = length $S0

  .local int multiplier
  multiplier = 1

  $S1 = substr $S0, 0, 1
  if $S1 == "+" goto positive
  # If the first character is -, assume a negative number.
  unless $S1 == "-" goto get_value
  multiplier = -1
positive:
  $S0 = substr $S0, 1
  # we check for the length below
  dec $I0
get_value:
  (value, $I1) = get_number($S0, 0)
  if null value goto NaN
  if $I0 != $I1 goto NaN
  value *= multiplier

done:
  .return(value)

NaN:
  .throw("Not a number!")
.end


## $Id$

=head1 NAME

src/builtins/match.pir - Perl6 builtins for smart matching

=head1 Functions

=over 4

=cut

.namespace []

.sub 'infix:~~' :multi()
    .param pmc topic
    .param pmc x
    .tailcall x.'ACCEPTS'(topic)
.end

.sub 'infix:!~~'
    .param pmc topic
    .param pmc x
    .tailcall x.'REJECTS'(topic)
.end

.sub 'make'
    .param pmc value
    $P0 = getinterp
    $P1 = $P0['lexpad';1]
    $P2 = $P1['$/']
    $P2.'result_object'(value)
.end

=back

=cut

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:

Add POD for 'make' builtin

## $Id$

=head1 NAME

src/builtins/match.pir - Perl6 builtins for smart matching

=head1 Functions

=over 4

=cut

.namespace []

.sub 'infix:~~' :multi()
    .param pmc topic
    .param pmc x
    .tailcall x.'ACCEPTS'(topic)
.end

.sub 'infix:!~~'
    .param pmc topic
    .param pmc x
    .tailcall x.'REJECTS'(topic)
.end

=item make($item)

Equivalent to C<$/.result_object($item)>.  This changes the item value of the current match object.

=cut

.sub 'make'
    .param pmc value
    $P0 = getinterp
    $P1 = $P0['lexpad';1]
    $P2 = $P1['$/']
    $P2.'result_object'(value)
.end

=back

=cut

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:


# $Id$

=head1 NAME

eval.imc - Integer arithmetic evaluation for Parrot m4

=head1 DESCRIPTION

Just a sample.
See languages/m4/Makefile on how to generate the needed shared lib.

=cut

.sub 'example' :main

    print "Trying to load shared library 'm4_evaluate'.\n"
    .local pmc m4_evaluate_lib
    m4_evaluate_lib = loadlib "m4_evaluate"
    if m4_evaluate_lib goto LOAD_FUNCTION
       printerr "Could not load 'm4_evaluate'.\n"
       end

LOAD_FUNCTION:
    print "Trying to load function 'm4_evaluate'.\n"
    .local pmc m4_evaluate
    m4_evaluate = dlfunc m4_evaluate_lib, "m4_evaluate", "it"
    if m4_evaluate goto EVALUATE_CODE
       printerr "Could not load m4_evaluate.\n"
       end

EVALUATE_CODE:
    .local string expression
    expression = '1 + 1 * 117'
    print "Evaluating expression: "
    print expression
    print "\n"
    .local int value
    ( value ) = m4_evaluate( expression )

INVOKE_COMPILED_CODE:
    print "evaluated: "
    print value
    print "\n"

.end

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4:

Remove remnants of the .imc file extension.

# $Id$

=head1 NAME

eval.pir - Integer arithmetic evaluation for Parrot m4

=head1 DESCRIPTION

Just a sample.
See languages/m4/Makefile on how to generate the needed shared lib.

=cut

.sub 'example' :main

    print "Trying to load shared library 'm4_evaluate'.\n"
    .local pmc m4_evaluate_lib
    m4_evaluate_lib = loadlib "m4_evaluate"
    if m4_evaluate_lib goto LOAD_FUNCTION
       printerr "Could not load 'm4_evaluate'.\n"
       end

LOAD_FUNCTION:
    print "Trying to load function 'm4_evaluate'.\n"
    .local pmc m4_evaluate
    m4_evaluate = dlfunc m4_evaluate_lib, "m4_evaluate", "it"
    if m4_evaluate goto EVALUATE_CODE
       printerr "Could not load m4_evaluate.\n"
       end

EVALUATE_CODE:
    .local string expression
    expression = '1 + 1 * 117'
    print "Evaluating expression: "
    print expression
    print "\n"
    .local int value
    ( value ) = m4_evaluate( expression )

INVOKE_COMPILED_CODE:
    print "evaluated: "
    print value
    print "\n"

.end

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4:


# Copyright (C) 2013, Parrot Foundation.

=head1 NAME

examples/benchmarks/sort_ffa.pir - Sort an FixedFloatArray of N floats

=head1 SYNOPSIS

    % time ./parrot examples/benchmarks/sort_ffa.pir

=head1 DESCRIPTION

Sorts an FixedFloatArray of N random integers using builtin sort
function for FixedFloatArray. The argument N is specified from the
command line.

=cut

.loadlib 'math_ops'

.sub main :main
  .param pmc argv
  .local int N, i, j

  N = argv[1]
  if N < 1 goto USE_DEFAULT_SIZE
  goto USE_DEFINED_SIZE

USE_DEFAULT_SIZE:
  N = 10000

USE_DEFINED_SIZE:
  $P0 = new ['FixedFloatArray'], N
  i = 0
  j = 0

LOOP:
  j = rand 0, N
  $P0[i] = j
  inc i
  if i < N goto LOOP

  $P0.'sort'()

.end

=cut

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:

Improve synopsis for sort benchmark

# Copyright (C) 2013, Parrot Foundation.

=head1 NAME

examples/benchmarks/sort_ffa.pir - Sort an FixedFloatArray of N floats

=head1 SYNOPSIS

    % time ./parrot examples/benchmarks/sort_ffa.pir 100000

Or use the default number of iterations:

    % time ./parrot examples/benchmarks/sort.pir

=head1 DESCRIPTION

Sorts an FixedFloatArray of N random integers using builtin sort
function for FixedFloatArray. The argument N is specified from the
command line.

=cut

.loadlib 'math_ops'

.sub main :main
  .param pmc argv
  .local int N, i, j

  N = argv[1]
  if N < 1 goto USE_DEFAULT_SIZE
  goto USE_DEFINED_SIZE

USE_DEFAULT_SIZE:
  N = 1000000

USE_DEFINED_SIZE:
  $P0 = new ['FixedFloatArray'], N
  i = 0
  j = 0

LOOP:
  j = rand 0, N
  $P0[i] = j
  inc i
  if i < N goto LOOP

  $P0.'sort'()

.end

=cut

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:


#!./parrot
# Copyright (C) 2012, Parrot Foundation.

.sub main :main
    .local pmc task, sayer, dummy
    sayer = get_global 'sayer'
    dummy = new ['Integer']
    task = new ['Task']
    setattribute task, 'code', sayer
    setattribute task, 'data', dummy
    schedule task
    wait task
.end

.sub sayer
    .param pmc proxy
    .local pmc interp, task, result_sub, result_task, dummy

    interp = getinterp
    dummy = new ['Integer']
    result_sub = get_global 'result_sub'

again:
    result_task = new ['Task']
    setattribute result_task, 'code', result_sub
    setattribute result_task, 'data', dummy
    interp.'schedule_proxied'(result_task, proxy)

    result_task = new ['Task']
    setattribute result_task, 'code', result_sub
    interp.'schedule_proxied'(result_task, proxy)

    goto again
.end

.sub result_sub
    .param pmc dummy
    .local pmc dummy2
.end

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:

Add some POD to a thread example

#!./parrot
# Copyright (C) 2012-2013, Parrot Foundation.

=head1 NAME

examples/threads/alloc_test.pir - Thread allocation examples

=head1 SYNOPSIS

    % ./parrot examples/threads/alloc_test.pir

=head1 DESCRIPTION

If you can explain what this example does in plain English, be my
guest.

=cut

.sub main :main
    .local pmc task, sayer, dummy
    sayer = get_global 'sayer'
    dummy = new ['Integer']
    task = new ['Task']
    setattribute task, 'code', sayer
    setattribute task, 'data', dummy
    schedule task
    wait task
.end

.sub sayer
    .param pmc proxy
    .local pmc interp, task, result_sub, result_task, dummy

    interp = getinterp
    dummy = new ['Integer']
    result_sub = get_global 'result_sub'

again:
    result_task = new ['Task']
    setattribute result_task, 'code', result_sub
    setattribute result_task, 'data', dummy
    interp.'schedule_proxied'(result_task, proxy)

    result_task = new ['Task']
    setattribute result_task, 'code', result_sub
    interp.'schedule_proxied'(result_task, proxy)

    goto again
.end

.sub result_sub
    .param pmc dummy
    .local pmc dummy2
.end

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:


## $Id$

=head1 NAME

src/builtins/named-unary.pir - Perl6 named unary builtins

=head1 Functions

=over 4

=cut

.namespace

=item defined($x)

Returns a true value if $x is defined, and a false value otherwise.

=cut

.sub 'defined'
    .param pmc x
    $I0 = defined x
    .return ($I0)
.end

=item rand($x)

Returns a random floating point number greater than or equal to zero and less
than $x.

=cut

.sub 'prefix:rand'
    .param num limit

    $P0 = new 'Random'
    $N0 = $P0
    $N0 *= limit

    .return ($N0)
.end

=back

=cut

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:

Make rand actually likely to generate a different sequence of numbers between runs.

## $Id$

=head1 NAME

src/builtins/named-unary.pir - Perl6 named unary builtins

=head1 Functions

=over 4

=cut

.namespace

=item defined($x)

Returns a true value if $x is defined, and a false value otherwise.

=cut

.sub 'defined'
    .param pmc x
    $I0 = defined x
    .return ($I0)
.end

=item rand($x)

Returns a random floating point number greater than or equal to zero and less
than $x.

=cut

.sub 'prefix:rand'
    .param num limit

    # For now, we'll seed it with the time. Likely sucks.
    $P0 = new 'Random'
    $I0 = time
    $P0 = $I0

    $N0 = $P0
    $N0 *= limit

    .return ($N0)
.end

=back

=cut

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:


.sub '' :anon :init :load

    # Numeric constants
    .local pmc pi, e, i
    pi = new ['Num']
    assign pi, 3.14159265358979323846264338327950288
    set_hll_global ['Numeric'], 'pi', pi
    set_hll_global 'pi', pi

    e  = new ['Num']
    assign e,  2.71828182845904523536028747135266249
    set_hll_global ['Numeric'], 'e', e
    set_hll_global 'e', e

.end

Add Radians, Degrees, Gradians, and Circles to emulate what TrigBase will look like when enums are available.

.sub '' :anon :init :load

    # Numeric constants
    .local pmc pi, e, i
    pi = new ['Num']
    assign pi, 3.14159265358979323846264338327950288
    set_hll_global ['Numeric'], 'pi', pi
    set_hll_global 'pi', pi

    e  = new ['Num']
    assign e,  2.71828182845904523536028747135266249
    set_hll_global ['Numeric'], 'e', e
    set_hll_global 'e', e

    .local pmc Radians, Degrees, Gradians, Circles
    Radians = new ['Int']
    assign Radians, 0
    set_hll_global ['Numeric'], 'Radians', Radians
    set_hll_global 'Radians', Radians

    Degrees = new ['Int']
    assign Degrees, 1
    set_hll_global ['Numeric'], 'Degrees', Degrees
    set_hll_global 'Degrees', Degrees

    Gradians = new ['Int']
    assign Gradians, 2
    set_hll_global ['Numeric'], 'Gradians', Gradians
    set_hll_global 'Gradians', Gradians

    Circles = new ['Int']
    assign Circles, 3
    set_hll_global ['Numeric'], 'Circles', Circles
    set_hll_global 'Circles', Circles

.end


=item !postcircumfix:<[ ]>

Because foreign (non-Rakudo) Parrot objects generally won't
understand the "postcircumfix:<[ ]>" method, we generate
postcircumfix as a private call to this function, and this
function then delegates to the appropriate method.  For PMCs
that don't have a postcircumfix:<[ ]> method, we directly
use the one in Positional.

=cut

.sub '!postcircumfix:<[ ]>'
    .param pmc invocant
    .param pmc args            :slurpy
    $I0 = can invocant, 'postcircumfix:<[ ]>'
    if $I0 goto object_method
    $I0 = isa invocant, 'Perl6Object'
    if $I0 goto object_method
  foreign:
    die "Can't postcircumfix:<[ ]> foreign objects yet."
  object_method:
    .tailcall invocant.'postcircumfix:<[ ]>'(args :flat)
.end

Add missing namespace decl to put postcircumfix:<[ ]> into global namespace.

=item !postcircumfix:<[ ]>

Because foreign (non-Rakudo) Parrot objects generally won't
understand the "postcircumfix:<[ ]>" method, we generate
postcircumfix as a private call to this function, and this
function then delegates to the appropriate method.  For PMCs
that don't have a postcircumfix:<[ ]> method, we directly
use the one in Positional.

=cut

.namespace []
.sub '!postcircumfix:<[ ]>'
    .param pmc invocant
    .param pmc args            :slurpy
    $I0 = can invocant, 'postcircumfix:<[ ]>'
    if $I0 goto object_method
    $I0 = isa invocant, 'Perl6Object'
    if $I0 goto object_method
  foreign:
    die "Can't postcircumfix:<[ ]> foreign objects yet."
  object_method:
    .tailcall invocant.'postcircumfix:<[ ]>'(args :flat)
.end


# we have to overload PCT::HLLCompiler's parse method to support P6Regex grammars

.namespace ['HLL';'Compiler']

.sub '' :anon :init :load
    load_bytecode 'PCT.pbc'
    .local pmc p6meta
    p6meta = get_hll_global 'P6metaclass'
    p6meta.'new_class'('HLL::Compiler', 'parent'=>'PCT::HLLCompiler')
.end

.sub 'parse' :method
    .param pmc source
    .param pmc options         :slurpy :named

    .local pmc parsegrammar, parseactions, match
    parsegrammar = self.'parsegrammar'()
    parseactions = self.'parseactions'()
    $I0 = isa parsegrammar, ['Regex';'Cursor']
    unless $I0 goto parse_old

    match = parsegrammar.'parse'(source, 'from'=>0, 'action'=>parseactions)
    unless match goto err_parsefail
    .return (match)

  err_parsefail:
    self.'panic'('Unable to parse source')
    .return (match)

  parse_old:
    $I0 = isa parsegrammar, ['NameSpace']
    if $I0 goto parse_old_1
    ##  switch from protoobjects to classes, then call parent
    $P0 = parsegrammar.'HOW'()
    $P0 = getattribute $P0, 'parrotclass'
    parsegrammar = $P0.'get_namespace'()
    self.'parsegrammar'(parsegrammar)

    $P0 = parseactions.'HOW'()
    $P0 = getattribute $P0, 'parrotclass'
    parseactions = $P0.'get_namespace'()
    self.'parseactions'(parseactions)

  parse_old_1:
    $P0 = get_hll_global ['PCT'], 'HLLCompiler'
    $P1 = find_method $P0, 'parse'
    .tailcall self.$P1(source, options :flat :named)
.end

Remove obsolete emulation of old grammar+action setup.

# we have to overload PCT::HLLCompiler's parse method to support P6Regex grammars

.namespace ['HLL';'Compiler']

.sub '' :anon :init :load
    load_bytecode 'PCT.pbc'
    .local pmc p6meta
    p6meta = get_hll_global 'P6metaclass'
    p6meta.'new_class'('HLL::Compiler', 'parent'=>'PCT::HLLCompiler')
.end

.sub 'parse' :method
    .param pmc source
    .param pmc options         :slurpy :named

    .local pmc parsegrammar, parseactions, match
    parsegrammar = self.'parsegrammar'()

    null parseactions
    $S0 = options['target']
#    if $S0 == 'parse' goto have_parseactions
    parseactions = self.'parseactions'()
  have_parseactions:

    match = parsegrammar.'parse'(source, 'from'=>0, 'action'=>parseactions)
    unless match goto err_parsefail
    .return (match)

  err_parsefail:
    self.'panic'('Unable to parse source')
    .return (match)
.end


.include "languages/tcl/lib/returncodes.pir"

.namespace [ "TclVar" ]

.HLL "Tcl", "tcl_group"

.cloneable()

=head2 __class_init

Define the attributes required for the class.

=cut

.sub __class_init :load
  $P0 = getclass "TclConst"
  $P1 = subclass $P0, "TclVar"
.end

.sub compile :method
    .param int register_num

    .local string pir_code
    pir_code = ""
    .local pmc args

    args = new .Array
    args = 4
    args[0] = register_num
    $S0 = self
    args[1] = $S0

    $S1 = sprintf ".local pmc read\nread=find_global \"_Tcl\", \"__read\"\n$P%i = read(\"%s\")\n", args
    pir_code .= $S1

    .return (register_num,pir_code)
.end

Make TclVar inherit from String instead of TclConst

.include "languages/tcl/lib/returncodes.pir"

.namespace [ "TclVar" ]

.HLL "Tcl", "tcl_group"

.cloneable()

=head2 __class_init

Define the attributes required for the class.

=cut

.sub __class_init :load
  $P0 = getclass "String"
  $P1 = subclass $P0, "TclVar"
.end

.sub compile :method
    .param int register_num

    .local string pir_code
    pir_code = ""
    .local pmc args

    args = new .Array
    args = 4
    args[0] = register_num
    $S0 = self
    args[1] = $S0

    $S1 = sprintf ".local pmc read\nread=find_global \"_Tcl\", \"__read\"\n$P%i = read(\"%s\")\n", args
    pir_code .= $S1

    .return (register_num,pir_code)
.end


.namespace []
.sub '!find_contextual'
    .param string name

    # first search caller scopes
    $P0 = find_dynamic_lex name
    unless null $P0 goto done

    # next, strip twigil and search PROCESS package
    .local string pkgname
    $S0     = substr name, 0, 1
    $S1     = substr name, 2
    pkgname = concat $S0, $S1
    $P0     = get_hll_global ['PROCESS'], pkgname
    unless null $P0 goto done
    $P0     = get_global pkgname
    unless null $P0 goto done

  fail:
    $P0 = '!FAIL'('Contextual ', name, ' not found')
  done:
    .return ($P0)
.end

Revert "[glue] Replaced a use of substr_s_i_i_s with a different op sequence to avoid"; it's unnecessary after more changes to Parrot immutable strings.

.namespace []
.sub '!find_contextual'
    .param string name

    # first search caller scopes
    $P0 = find_dynamic_lex name
    unless null $P0 goto done

    # next, strip twigil and search PROCESS package
    .local string pkgname
    pkgname = clone name
    substr pkgname, 1, 1, ''
    $P0 = get_hll_global ['PROCESS'], pkgname
    unless null $P0 goto done
    $P0 = get_global pkgname
    unless null $P0 goto done

  fail:
    $P0 = '!FAIL'('Contextual ', name, ' not found')
  done:
    .return ($P0)
.end


Add simple Proof-of-concept non-abstracted script, because Parrot objects and namespaces are pissing me off

# Copyright (C) 2009, Jonathan "Duke" Leto

=head1 AUTHOR

Written and maintained by Jonathan "Duke" Leto C<< jonathan@leto.net >>.

=cut

.sub main :main
    .local int num_tests
    $S0 = "1..5\nFoobar!"
    num_tests = parse_plan($S0)
    say num_tests
.end

.sub parse_plan
    .param string tap
    .local pmc plan_line
    .local pmc plan_parts
    .local int num_expected_tests
    .local string delim

    plan_line = new 'ResizablePMCArray'
    delim               = "\n"
    split plan_line, delim, tap
    $S0                 = plan_line[0]
    unless $S0 goto error
    delim               = ".."
    plan_parts = new 'ResizablePMCArray'
    split plan_parts, delim, $S0

    unless plan_parts goto plan_error
    num_expected_tests  = plan_parts[1]

    .return (num_expected_tests)
  error:
    die 'Invalid TAP Stream'
  plan_error:
    die 'Invalid TAP Plan'
.end

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:


## $Id$

=head1 TITLE

Multi - Perl 6 multi-dispatch routine

=head1 SUBROUTINES

=over 4

=item onload()

=cut

.namespace [ 'Multi' ]

.sub 'onload' :anon :init :load
    .local pmc p6meta, proto
    p6meta = get_hll_global ['Perl6Object'], '$!P6META'
    proto = p6meta.'new_class'('Multi', 'parent'=>'Perl6MultiSub Code')
    p6meta.'register'('Perl6MultiSub', 'protoobject'=>proto)
.end

.sub 'Scalar' :method
    .return (self)
.end

=back

=cut

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:

Revert an accidential change from earlier debugging.

## $Id$

=head1 TITLE

Multi - Perl 6 multi-dispatch routine

=head1 SUBROUTINES

=over 4

=item onload()

=cut

.namespace [ 'Multi' ]

.sub 'onload' :anon :init :load
    .local pmc p6meta, proto
    p6meta = get_hll_global ['Perl6Object'], '$!P6META'
    proto = p6meta.'new_class'('Multi', 'parent'=>'Perl6MultiSub Code Any')
    p6meta.'register'('Perl6MultiSub', 'parent'=>proto, 'protoobject'=>proto)
.end

.sub 'Scalar' :method
    .return (self)
.end

=back

=cut

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:


# Copyright (C) 2009, Jonathan "Duke" Leto

=head1 AUTHOR

Written and maintained by Jonathan "Duke" Leto C<< jonathan@leto.net >>.

=cut

.namespace [ 'Tapir'; 'Parser' ]

#.sub _initialize :load
#
#    .local pmc parser
#    set_hll_global [ 'Tapir'; 'Parser' ], '_parser', parser
#.end

# parse_plan returns the expected number of test given a TAP stream as a string

.sub parse_plan :method
    .local string tap
    .local pmc plan_line
    .local pmc plan_parts
    .local int num_expected_tests
    .local string delim

    plan_line = new 'ResizeablePMCArray'
    delim               = "\n"
    split plan_line, delim, tap
    $S0                 = plan_line[0]
    unless $S0 goto error
    delim               = ".."
    plan_parts = new 'ResizeablePMCArray'
    split plan_parts, delim, $S0

    unless plan_parts goto plan_error
    num_expected_tests  = plan_parts[0]

    .return (num_expected_tests)
  error:
    die 'Invalid TAP Stream'
  plan_error:
    die 'Invalid TAP Plan'
.end

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:

Make parse_plan a method that takes a tap string as an argument

# Copyright (C) 2009, Jonathan "Duke" Leto

=head1 AUTHOR

Written and maintained by Jonathan "Duke" Leto C<< jonathan@leto.net >>.

=cut

.namespace [ 'Tapir'; 'Parser' ]

#.sub _initialize :load
#
#    .local pmc parser
#    set_hll_global [ 'Tapir'; 'Parser' ], '_parser', parser
#.end

# parse_plan returns the expected number of test given a TAP stream as a string

.sub parse_plan :method
    .param string tap
    .local pmc plan_line
    .local pmc plan_parts
    .local int num_expected_tests
    .local string delim

    plan_line = new 'ResizeablePMCArray'
    delim               = "\n"
    split plan_line, delim, tap
    $S0                 = plan_line[0]
    unless $S0 goto error
    delim               = ".."
    plan_parts = new 'ResizeablePMCArray'
    split plan_parts, delim, $S0

    unless plan_parts goto plan_error
    num_expected_tests  = plan_parts[0]

    .return (num_expected_tests)
  error:
    die 'Invalid TAP Stream'
  plan_error:
    die 'Invalid TAP Plan'
.end

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:


## $Id$

=head1 NAME

src/builtins/match.pir - Perl6 builtins for smart matching

=head1 Functions

=over 4

=cut

.namespace []

.sub 'infix:~~' :multi()
    .param pmc topic
    .param pmc x
    .tailcall x.'ACCEPTS'(topic)
.end

.sub 'infix:!~~'
    .param pmc topic
    .param pmc x
    .tailcall x.'REJECTS'(topic)
.end

=item make($item)

Equivalent to C<$/."!make"($item)>.  This sets the ast value of
the current match object.

=cut

.sub 'make'
    .param pmc value
    $P0 = getinterp
    $P1 = $P0['lexpad';1]
    $P2 = $P1['$/']
    $P2.'!make'(value)
.end

=back

=cut

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:

Update make() to give a slightly more useful warning when $/ not set.

## $Id$

=head1 NAME

src/builtins/match.pir - Perl6 builtins for smart matching

=head1 Functions

=over 4

=cut

.namespace []

.sub 'infix:~~' :multi()
    .param pmc topic
    .param pmc x
    .tailcall x.'ACCEPTS'(topic)
.end

.sub 'infix:!~~'
    .param pmc topic
    .param pmc x
    .tailcall x.'REJECTS'(topic)
.end

=item make($item)

Equivalent to C<$/."!make"($item)>.  This sets the ast value of
the current match object.

=cut

.sub 'make'
    .param pmc value
    $P0 = getinterp
    $P1 = $P0['lexpad';1]
    $P2 = $P1['$/']
    $I0 = can $P2, '!make'
    unless $I0 goto err_make
    $P2.'!make'(value)
    .return ()
  err_make:
    'die'("make() cannot set result of non-Match object in $/")
    .return ()
.end

=back

=cut

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:


Add a file missed out in the previous ci. Oops.

## $Id$

=head1 NAME

src/classes/Role.pir - methods for the Role class

=head1 Methods

=over 4

=cut

.namespace ['Role']

=item ACCEPTS(topic)

=cut

.sub 'ACCEPTS' :method
    .param pmc topic
    $I0 = does topic, self
    .return 'prefix:?'($I0)
.end

=back

=cut

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:


# Copyright (C) 2004-2009, Parrot Foundation.
# $Id$

.sub bench :main
.include "pmctypes.pasm"
.include "mmd.pasm"
   .local int i
   .local pmc r
   .local pmc a
   .local pmc b
   a = new 'Integer'
   b = new 'Integer'
   r = new 'Integer'
   a = 7
   b = 6
   i = 1
loop:
   r = a * b
   inc i
   if i <= 50000 goto loop
   print r
   print "\n"
   end
.end

.sub my_mul :multi(Integer, Integer, Integer)
   .param pmc left
   .param pmc right
   .param pmc dest
   $I0 = left
   $I1 = right
   $I2 = $I0 * $I1
   dest = $I2
   .return (dest)
.end

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:

Remove .include 'mmd.pasm'. mmd.pasm doesn't exists anymore

# Copyright (C) 2004-2009, Parrot Foundation.
# $Id$

.sub bench :main
.include "pmctypes.pasm"
   .local int i
   .local pmc r
   .local pmc a
   .local pmc b
   a = new 'Integer'
   b = new 'Integer'
   r = new 'Integer'
   a = 7
   b = 6
   i = 1
loop:
   r = a * b
   inc i
   if i <= 50000 goto loop
   print r
   print "\n"
   end
.end

.sub my_mul :multi(Integer, Integer, Integer)
   .param pmc left
   .param pmc right
   .param pmc dest
   $I0 = left
   $I1 = right
   $I2 = $I0 * $I1
   dest = $I2
   .return (dest)
.end

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:


.namespace [ "_Tcl" ]

=head2 _Tcl::__list

Given a PMC, get a list from it. If the PMC is a TclLst,
this is as simple as returning the list. If it's a string,
use __stringToList.

=cut

.sub __list
  .param pmc value

  $I0 = typeof value
  if $I0 == .TclList goto done

  $S0 = value
  .return __stringToList($S0)

done:
  .return(value)
.end

=head2 _Tcl::__number

Given a PMC, get a number from it.

=cut

.sub __number
  .param pmc value

  $I0 = typeof value
  if $I0 == .TclInt goto done
  if $I0 == .TclFloat goto done

  $S0 = value
  $I0 = length $S0

  .local int multiplier
  multiplier = 1

  $S1 = substr $S0, 0, 1
  # If the first character is -, assume a negative number.
  unless $S1 == "-" goto get_value
  multiplier = -1
  $I0 = length $S0
  dec $I0
  $S0 = substr $S0, 1, $I0
get_value:
  (value, $I1) = get_number($S0, 0)
  if_null value, NaN
  if $I0 != $I1 goto NaN
  value *= multiplier

done:
  .return(value)

NaN:
  .throw("Not a number!")
.end

Make __number() handle explicit + numbers

.namespace [ "_Tcl" ]

=head2 _Tcl::__list

Given a PMC, get a list from it. If the PMC is a TclLst,
this is as simple as returning the list. If it's a string,
use __stringToList.

=cut

.sub __list
  .param pmc value

  $I0 = typeof value
  if $I0 == .TclList goto done

  $S0 = value
  .return __stringToList($S0)

done:
  .return(value)
.end

=head2 _Tcl::__number

Given a PMC, get a number from it.

=cut

.sub __number
  .param pmc value

  $I0 = typeof value
  if $I0 == .TclInt goto done
  if $I0 == .TclFloat goto done

  $S0 = value
  $I0 = length $S0

  .local int multiplier
  multiplier = 1

  $S1 = substr $S0, 0, 1
  if $S1 == "+" goto positive
  # If the first character is -, assume a negative number.
  unless $S1 == "-" goto get_value
  multiplier = -1
positive:
  $S0 = substr $S0, 1
  # we check for the length below
  dec $I0
get_value:
  (value, $I1) = get_number($S0, 0)
  if null value goto NaN
  if $I0 != $I1 goto NaN
  value *= multiplier

done:
  .return(value)

NaN:
  .throw("Not a number!")
.end


# $Id$

=head1 NAME

HLL - Parrot HLL library

=head1 DESCRIPTION

This file brings together the various modules needed for HLL::Compiler
and HLL::Grammar.

=cut

.sub '' :anon :load :init
    load_bytecode 'Regex.pbc'
.end

.include 'src/cheats/hll-compiler.pir'
.include 'src/cheats/hll-grammar.pir'
.include 'src/cheats/parrot-callcontext.pir'
.include 'gen/hllgrammar-grammar.pir'
.include 'gen/hllgrammar-actions.pir'
.include 'gen/hllcompiler.pir'

=head1 AUTHOR

Patrick Michaud <pmichaud@pobox.com> is the author and maintainer.

=head1 COPYRIGHT

Copyright (C) 2009, The Perl Foundation.

=cut

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:

Add some pod directives to help out Parrot's "make codetest" target.

# $Id$

=head1 NAME

HLL - Parrot HLL library

=head1 DESCRIPTION

This file brings together the various modules needed for HLL::Compiler
and HLL::Grammar.

=over 4

=cut

.sub '' :anon :load :init
    load_bytecode 'Regex.pbc'
.end

.include 'src/cheats/hll-compiler.pir'
.include 'src/cheats/hll-grammar.pir'
.include 'src/cheats/parrot-callcontext.pir'
.include 'gen/hllgrammar-grammar.pir'
.include 'gen/hllgrammar-actions.pir'
.include 'gen/hllcompiler.pir'

=back

=head1 AUTHOR

Patrick Michaud <pmichaud@pobox.com> is the author and maintainer.

=head1 COPYRIGHT

Copyright (C) 2009, The Perl Foundation.

=cut

# Local Variables:
#   mode: pir
#   fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:


{
  mpower: {
    "mpower.02": {
      address: "192.168.2.226:22",
      user: "ubnt",
      ports: {
        "skia-e-linux-001": 1,
        "skia-e-linux-002": 2,
        "skia-e-linux-003": 3,
        "skia-e-linux-004": 4,
        "mp-2-test-relay": 5
      }
    },
    "mpower.03": {
      address: "192.168.2.212:22",
      user: "ubnt",
      ports: {
        "skia-e-linux-013": 1,
        "skia-e-linux-014": 2,
        "skia-e-linux-015": 3,
        "skia-e-linux-016": 4,
        "skia-e-linux-017": 5,
        "skia-e-linux-018": 6,
        "test-relay": 7
      }
    }
  }
}

Remove deleted bots from powercycle config.


{
  authorized_users: [
    "google.com", "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com",
    "chrome-gold-internal@chops-service-accounts.iam.gserviceaccount.com",
    "chrome-gold@chops-service-accounts.iam.gserviceaccount.com",
  ],
  client_secret_file: "/etc/skia.org/login.json",
  disable_sql_exp_cl: true,
  flaky_trace_threshold: 2, // traces creating 3 or more unique digests are flaky.
  force_login: true, // This instance requires authentication. It has a public view (chrome-public)
  frontend: {
    baseRepoURL: "<inherited from git_repo_url>",
    defaultCorpus: "android-render-tests",
    title: "Chrome Gold",
  },
  prom_port: ":20000",
  ready_port: ":8000",
  public_site_url: "https://chrome-public-gold.skia.org",
  resources_path: "/usr/local/share/frontend/dist",
  tile_freshness: "1m",
  trace_bt_table: "gold-chrome",

  // These values affect the k8s deployment; they are not read in by the binary.
  K8S_CPU: 4,
  K8S_LOGIN_SECRETS: "skia-org-legacy-login-secrets",
  K8S_MEMORY: "4Gi",
}

Add support for chrome service accounts

{
  authorized_users: [
    "google.com", "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com",
    "chrome-gold-internal@chops-service-accounts.iam.gserviceaccount.com",
    "chrome-gold@chops-service-accounts.iam.gserviceaccount.com",
    "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
    "chrome-tester@chops-service-accounts.iam.gserviceaccount.com"
  ],
  client_secret_file: "/etc/skia.org/login.json",
  disable_sql_exp_cl: true,
  flaky_trace_threshold: 2, // traces creating 3 or more unique digests are flaky.
  force_login: true, // This instance requires authentication. It has a public view (chrome-public)
  frontend: {
    baseRepoURL: "<inherited from git_repo_url>",
    defaultCorpus: "android-render-tests",
    title: "Chrome Gold",
  },
  prom_port: ":20000",
  ready_port: ":8000",
  public_site_url: "https://chrome-public-gold.skia.org",
  resources_path: "/usr/local/share/frontend/dist",
  tile_freshness: "1m",
  trace_bt_table: "gold-chrome",

  // These values affect the k8s deployment; they are not read in by the binary.
  K8S_CPU: 4,
  K8S_LOGIN_SECRETS: "skia-org-legacy-login-secrets",
  K8S_MEMORY: "4Gi",
}


{
  cl_comment_template: "Gold has detected about {{.NumNewDigests}} new digest(s) on patchset {{.PatchsetOrder}}.\n\
View them at {{.InstanceURL}}/cl/{{.CRS}}/{{.ChangelistID}}",
  changelist_diff_period: "5m",
  comment_on_cls_period: "5m",
  primary_branch_diff_period: "5m",
  update_traces_ignore_period: "1m",
  prom_port: ":20000",
  ready_port: ":8000"
}

Disable commenting on CLs for flutter-engine

{
  cl_comment_template: "Gold has detected about {{.NumNewDigests}} new digest(s) on patchset {{.PatchsetOrder}}.\n\
View them at {{.InstanceURL}}/cl/{{.CRS}}/{{.ChangelistID}}",
  changelist_diff_period: "5m",
  comment_on_cls_period: "0",
  primary_branch_diff_period: "5m",
  update_traces_ignore_period: "1m",
  prom_port: ":20000",
  ready_port: ":8000"
}


{   "image": "",
    "name": "",
    "version": "0.0.0",
    "github": {
        "user": "",
        "repo": ""
    },

    "procedure": [

        {   "title": "",
            "type": "template",

            "sourcedir": "leto_config/templates",
            "templates": [
                {   "name": "template",
                    "dest": "some/output/directory/filename.extension"
                }
            ]
        },

        {   "title": "Change some stuff",
            "type": "change",

            "ruleset": "leto_config/rules.js",
            "changes": [
                {   "rule": "ruleName",
                    "file": "text/file/you/want/to/change.extension",
                    "start": 0,
                    "end": 579297835
                },
            ]
        }
    ]
}

Change around the full template skeliton

{   "image": "",
    "name": "",
    "version": "0.0.0",
    "github": {
        "user": "",
        "repo": ""
    },

    "procedure": [

        {   "title": "",
            "type": "template",

            "sourcedir": "leto_config/templates",
            "templates": [
                {   "name": "template",
                    "dest": "some/output/directory/filename.extension"
                }
            ]
        },

        {   "title": "",
            "type": "change",

            "ruleset": "leto_config/rules.js",
            "changes": [
                {   "rule": "ruleName",
                    "file": "text/file/you/want/to/change.extension",
                },
            ]
        }
    ]
}


{
  "apps": [

    {
      "name": "lol-item-sets-generator.org",
      "script": "build/bundle/main.js",
      "env_production": {
        "NODE_ENV": "production",
        "MONGO_URL": "mongodb://localhost:27017/myapp",
        "ITEM_SETS_ZIP_LOCATION": "~/lol-item-sets-generator-org/output/ItemSets.zip",
        "ROOT_URL": "https://www.domain.com",
        "ADMIN_MAIL": "name@domain.com",
        "KADIRA_APP_ID": "APP_ID",
        "KADIRA_APP_SECRET": "APP_SECRET",
        "PORT": 9000
      },
      "args": ["--release"],
      "port": 9000,
      "watch": false,
      "source_map_support": true,
      "instances": 0,
      "exec_mode": "cluster"
    }

  ]

}

Append 'production' to PM2 process name

{
  "apps": [

    {
      "name": "lol-item-sets-generator.org",
      "script": "build/bundle/main.js",
      "env_production": {
        "NODE_ENV": "production",
        "MONGO_URL": "mongodb://localhost:27017/myapp",
        "ITEM_SETS_ZIP_LOCATION": "~/lol-item-sets-generator-org/output/ItemSets.zip",
        "ROOT_URL": "https://www.domain.com",
        "ADMIN_MAIL": "name@domain.com",
        "KADIRA_APP_ID": "APP_ID",
        "KADIRA_APP_SECRET": "APP_SECRET",
        "PORT": 9000
      },
      "args": ["--release"],
      "port": 9000,
      "watch": false,
      "source_map_support": true,
      "instances": 0,
      "exec_mode": "cluster",
      "append_env_to_name": true,
    }

  ]

}


{
    "BASELINE_SERVER_IMAGE": "gcr.io/skia-public/gold-baseline-server:2020-10-16T00_23_04Z-lovisolo-a8e092a-clean",
    "DIFF_SERVER_IMAGE":     "gcr.io/skia-public/gold-diff-server:2020-10-21T15_10_10Z-kjlubick-3de9e10-clean",
    "INGESTION_BT_IMAGE":    "gcr.io/skia-public/gold-ingestion:2020-10-21T15_12_13Z-kjlubick-3de9e10-clean",
    "SKIACORRECTNESS_IMAGE": "gcr.io/skia-public/gold-skiacorrectness:2020-10-15T21_02_09Z-lovisolo-c61683d-clean",

    // Services for testing goldpushk.
    "HEALTHY_SERVER_IMAGE": "gcr.io/skia-public/goldpushk-healthy-server:2019-10-16T18_39_09Z-lovisolo-9b77357-clean",
    "CRASHING_SERVER_IMAGE": "gcr.io/skia-public/goldpushk-crashing-server:2019-10-02T20_06_33Z-lovisolo-485c78d-clean",
}

Update skiacorrectness and baseline-server to LKGR.

{
    "BASELINE_SERVER_IMAGE": "gcr.io/skia-public/gold-baseline-server:2020-11-05T19_17_03Z-lovisolo-010f3bb-clean",
    "DIFF_SERVER_IMAGE":     "gcr.io/skia-public/gold-diff-server:2020-10-21T15_10_10Z-kjlubick-3de9e10-clean",
    "INGESTION_BT_IMAGE":    "gcr.io/skia-public/gold-ingestion:2020-10-21T15_12_13Z-kjlubick-3de9e10-clean",
    "SKIACORRECTNESS_IMAGE": "gcr.io/skia-public/gold-skiacorrectness:2020-11-05T19_15_25Z-lovisolo-010f3bb-clean",

    // Services for testing goldpushk.
    "HEALTHY_SERVER_IMAGE": "gcr.io/skia-public/goldpushk-healthy-server:2019-10-16T18_39_09Z-lovisolo-9b77357-clean",
    "CRASHING_SERVER_IMAGE": "gcr.io/skia-public/goldpushk-crashing-server:2019-10-02T20_06_33Z-lovisolo-485c78d-clean",
}


{
    "BASELINE_SERVER_IMAGE": "gcr.io/skia-public/gold-baseline-server:2020-02-04T17_26_45Z-kjlubick-916adf2-clean",
    "DIFF_SERVER_IMAGE":     "gcr.io/skia-public/gold-diff-server:2020-02-04T17_25_34Z-kjlubick-916adf2-clean",
    "INGESTION_BT_IMAGE":    "gcr.io/skia-public/gold-ingestion:2020-02-07T16_20_58Z-lovisolo-09e87c3-clean",
    "SKIACORRECTNESS_IMAGE": "gcr.io/skia-public/gold-skiacorrectness:2020-02-04T17_28_25Z-kjlubick-916adf2-clean",

    // Services for testing goldpushk.
    "HEALTHY_SERVER_IMAGE": "gcr.io/skia-public/goldpushk-healthy-server:2019-10-16T18_39_09Z-lovisolo-9b77357-clean",
    "CRASHING_SERVER_IMAGE": "gcr.io/skia-public/goldpushk-crashing-server:2019-10-02T20_06_33Z-lovisolo-485c78d-clean",
}

Update lkgr to include multiple CIS ingestion

{
    "BASELINE_SERVER_IMAGE": "gcr.io/skia-public/gold-baseline-server:2020-02-04T17_26_45Z-kjlubick-916adf2-clean",
    "DIFF_SERVER_IMAGE":     "gcr.io/skia-public/gold-diff-server:2020-02-04T17_25_34Z-kjlubick-916adf2-clean",
    "INGESTION_BT_IMAGE":    "gcr.io/skia-public/gold-ingestion:2020-02-12T17_25_11Z-kjlubick-5a774a5-clean",
    "SKIACORRECTNESS_IMAGE": "gcr.io/skia-public/gold-skiacorrectness:2020-02-12T17_30_21Z-kjlubick-5a774a5-clean",

    // Services for testing goldpushk.
    "HEALTHY_SERVER_IMAGE": "gcr.io/skia-public/goldpushk-healthy-server:2019-10-16T18_39_09Z-lovisolo-9b77357-clean",
    "CRASHING_SERVER_IMAGE": "gcr.io/skia-public/goldpushk-crashing-server:2019-10-02T20_06_33Z-lovisolo-485c78d-clean",
}


{
  "apps": [

    {
      "name": "league-tooltips-demo",
      "script": "app.js",
      "env": {
        "KEY_RIOT": "API_KEY",
        "PORT": 9000
      },
      "args": ["--release"],
      "watch": false,
    }

  ]

}

Append 'production' to PM2 process name

{
  "apps": [

    {
      "name": "league-tooltips-demo",
      "script": "app.js",
      "env": {
        "KEY_RIOT": "API_KEY",
        "PORT": 9000
      },
      "args": ["--release"],
      "watch": false,
      "append_env_to_name": true,
    }

  ]

}


{
  extends: ['config:base'],
  regexManagers: [
    {
      fileMatch: ['^*.gemspec'],
      matchStrings: [
        '^.*add.*dependency\\s[\'"](?<depName>[^\'"]*)[\'"],\\s*[\'"](?<currentValue>[^\'"]*)[\'"]',
      ],
      datasourceTemplate: 'rubygems',
    },
  ],
}

Revert "Fix regexManagers for gemspec"

{
  extends: ['config:base'],
  regexManagers: [
    {
      fileMatch: ['^*.gemspec'],
      matchStrings: [
        ".*add.*dependency '(?<depName>.*?)', '(?<currentValue>.*?)'",
      ],
      datasourceTemplate: 'rubygems',
    },
  ],
}


{
  authorized_users: [
    "google.com",
  ],
  client_secret_file: "/etc/skia.org/login.json",
  frontend: {
    baseRepoURL: "<inherited from git_repo_url>",
    defaultCorpus: "spec",
    title: "Gold for Lottie Animation Community",
  },
  prom_port: ":20000",
  ready_port: ":8000",
  resources_path: "/usr/local/share/frontend/dist",

  // These values affect the k8s deployment; they are not read in by the binary.
  K8S_CPU: 1,
  K8S_LOGIN_SECRETS: "skia-org-legacy-login-secrets",
  K8S_MEMORY: "4Gi",
}

Fix default corpus for lottie-spec

{
  authorized_users: [
    "google.com",
  ],
  client_secret_file: "/etc/skia.org/login.json",
  frontend: {
    baseRepoURL: "<inherited from git_repo_url>",
    defaultCorpus: "lottie-animation-community",
    title: "Gold for Lottie Animation Community",
  },
  prom_port: ":20000",
  ready_port: ":8000",
  resources_path: "/usr/local/share/frontend/dist",

  // These values affect the k8s deployment; they are not read in by the binary.
  K8S_CPU: 1,
  K8S_LOGIN_SECRETS: "skia-org-legacy-login-secrets",
  K8S_MEMORY: "4Gi",
}


// This is the pm2 configuration file for npms-api
{
    apps: [
        {
            name: 'npms-api',
            script: './server.js',
            args: [],
            instances: 3,
            env : { NODE_ENV: 'production' },
            max_memory_restart: '2018M',  // Restart if it's getting close to the limit
            node_args: '--max_old_space_size=2048',
            pmx: false,  // We were experiecing PMX has a lot of memory leaks, see: https://github.com/keymetrics/pmx/issues/23
        },
    ],
    deploy: {
        production: {
            user: 'www',
            host: '163.172.160.79',
            ref: 'origin/master',
            repo: 'https://github.com/npms-io/npms-api.git',
            path: '/home/www/npms-api',
            'post-deploy': '\
cp ../local.json5 ./config/ && \
npm update --loglevel http --production && \
pm2 startOrRestart ecosystem.json5 --env production',
        },
    },
}

Enable pmx again, leak was caused by an external dep that is not used here.

// This is the pm2 configuration file for npms-api
{
    apps: [
        {
            name: 'npms-api',
            script: './server.js',
            args: [],
            instances: 3,
            env : { NODE_ENV: 'production' },
            max_memory_restart: '2018M',  // Restart if it's getting close to the limit
            node_args: '--max_old_space_size=2048',
        },
    ],
    deploy: {
        production: {
            user: 'www',
            host: '163.172.160.79',
            ref: 'origin/master',
            repo: 'https://github.com/npms-io/npms-api.git',
            path: '/home/www/npms-api',
            'post-deploy': '\
cp ../local.json5 ./config/ && \
npm update --loglevel http --production && \
pm2 startOrRestart ecosystem.json5 --env production',
        },
    },
}


// This is the pm2 configuration file for npms-badges
{
    apps: [
        {
            name: 'npms-badges',
            script: './server.js',
            args: [],
            instances: 2,
            env : { NODE_ENV: 'production' },
            max_memory_restart: '1500M'
        },
    ],
    deploy: {
        production: {
            user: 'www',
            host: '163.172.160.79',
            ref: 'origin/master',
            repo: 'https://github.com/npms-io/npms-badges.git',
            path: '/home/www/npms-badges',
            'post-deploy': '\
cp ../local.json5 ./config/ && \
npm update --loglevel http --production && \
pm2 startOrRestart ecosystem.json5 --env production',
        },
    },
}

Disable pmx and tweak memory limits.

// This is the pm2 configuration file for npms-badges
{
    apps: [
        {
            name: 'npms-badges',
            script: './server.js',
            args: [],
            instances: 2,
            env : { NODE_ENV: 'production' },
            max_memory_restart: '2018M',  // Restart if it's getting close to the limit
            node_args: '--max_old_space_size=2048',
            pmx: false,  // We were experiecing PMX has a lot of memory leaks, see: https://github.com/keymetrics/pmx/issues/23
        },
    ],
    deploy: {
        production: {
            user: 'www',
            host: '163.172.160.79',
            ref: 'origin/master',
            repo: 'https://github.com/npms-io/npms-badges.git',
            path: '/home/www/npms-badges',
            'post-deploy': '\
cp ../local.json5 ./config/ && \
npm update --loglevel http --production && \
pm2 startOrRestart ecosystem.json5 --env production',
        },
    },
}


{
   "name":"server-stores",
   "version":"1.0.0",
   "description":"Server stores support JS-KIT",
   "author":"Tony Mobily",
   "moduleDependencies":[
      "server-base"
   ],
   "position": 110,
   "manipulate":{
      "json":{
         "server/package.json":[
            {
               "op":"set",
               "key":"dependencies.jsonreststores",
               "value":"^2.x.x"
            },
            {
               "op":"set",
               "key":"dependencies.simpleschema",
               "value":"^2.x.x"
            }

         ]
      },
      "text":{
         "server/app.js":[
            {
               "op":"insert",
               "position":"before",
               "newlineAfter":true,
               "anchorPoint":"/* Loaded modules -- end */",
               "value":"const JsonRestStores = require('jsonreststores')"
            },
            {
               "op":"insert",
               "position":"before",
               "newlineAfter":true,
               "anchorPoint":"/* App routes -- end */",
               "value":"// Automatically include all stores in stores/1.0.0 and listen to them all\nJsonRestStores.requireStoresFromPath(path.join(__dirname, 'stores/1.0.0'), app)\n"
            }
         ]
      }
   }
}

Include default version in app

server-stores

Server stores support JS-KIT

// Automatically include all stores in stores/<%-vars.defaultStoreVersion%> and listen to them all
JsonRestStores.requireStoresFromPath(path.join(__dirname, 'stores/<%-vars.defaultStoreVersion%>'), app)


// This is the pm2 configuration file for npms-badges
{
    apps: [
        {
            name: 'npms-badges',
            script: './server.js',
            args: [],
            instances: 2,
            env : { NODE_ENV: 'production' },
            max_memory_restart: '2018M',  // Restart if it's getting close to the limit
            node_args: '--max_old_space_size=2048',
            pmx: false,  // We were experiecing PMX has a lot of memory leaks, see: https://github.com/keymetrics/pmx/issues/23
        },
    ],
    deploy: {
        production: {
            user: 'www',
            host: '163.172.160.79',
            ref: 'origin/master',
            repo: 'https://github.com/npms-io/npms-badges.git',
            path: '/home/www/npms-badges',
            'post-deploy': '\
cp ../local.json5 ./config/ && \
npm update --loglevel http --production && \
pm2 startOrRestart ecosystem.json5 --env production',
        },
    },
}

Enable pmx again, leak was caused by an external dep that is not used here.

// This is the pm2 configuration file for npms-badges
{
    apps: [
        {
            name: 'npms-badges',
            script: './server.js',
            args: [],
            instances: 2,
            env : { NODE_ENV: 'production' },
            max_memory_restart: '2018M',  // Restart if it's getting close to the limit
            node_args: '--max_old_space_size=2048',
        },
    ],
    deploy: {
        production: {
            user: 'www',
            host: '163.172.160.79',
            ref: 'origin/master',
            repo: 'https://github.com/npms-io/npms-badges.git',
            path: '/home/www/npms-badges',
            'post-deploy': '\
cp ../local.json5 ./config/ && \
npm update --loglevel http --production && \
pm2 startOrRestart ecosystem.json5 --env production',
        },
    },
}


{
  authorized_users: [
    "google.com", "angle-gold@chops-service-accounts.iam.gserviceaccount.com",
    "chrome-gold-internal@chops-service-accounts.iam.gserviceaccount.com",
  ],
  client_secret_file: "/etc/skia.org/login.json",
  disable_sql_exp_cl: true,
  flaky_trace_threshold: 10000, // no trace is flaky
  frontend: {
    baseRepoURL: "<inherited from git_repo_url>",
    defaultCorpus: "angle",
    title: "Gold for ANGLE",
  },
  prom_port: ":20000",
  ready_port: ":8000",
  resources_path: "/usr/local/share/frontend/dist",
  tile_freshness: "1m",
  trace_bt_table: "gold-angle",

  // These values affect the k8s deployment; they are not read in by the binary.
  K8S_CPU: 4,
  K8S_LOGIN_SECRETS: "skia-org-legacy-login-secrets",
  K8S_MEMORY: "4Gi",
}

Update service accounts for angle

{
  authorized_users: [
    "google.com", "angle-gold@chops-service-accounts.iam.gserviceaccount.com",
    "chrome-gold-internal@chops-service-accounts.iam.gserviceaccount.com",
    "chrome-tester@chops-service-accounts.iam.gserviceaccount.com",
    "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
  ],
  client_secret_file: "/etc/skia.org/login.json",
  disable_sql_exp_cl: true,
  flaky_trace_threshold: 10000, // no trace is flaky
  frontend: {
    baseRepoURL: "<inherited from git_repo_url>",
    defaultCorpus: "angle",
    title: "Gold for ANGLE",
  },
  prom_port: ":20000",
  ready_port: ":8000",
  resources_path: "/usr/local/share/frontend/dist",
  tile_freshness: "1m",
  trace_bt_table: "gold-angle",

  // These values affect the k8s deployment; they are not read in by the binary.
  K8S_CPU: 4,
  K8S_LOGIN_SECRETS: "skia-org-legacy-login-secrets",
  K8S_MEMORY: "4Gi",
}


{
  extends: ['config:base'],
  timezone: 'Europe/Zurich',
  schedule: 'after 1am on Saturday',
  labels: ['dependencies'],
  separateMajorMinor: true,
  separateMinorPatch: true,
  prHourlyLimit: 0,
  prConcurrentLimit: 0,
  lockFileMaintenance: {enabled: true, automerge: true},
  baseBranches: ['master', '2.7'],
  regexManagers: [
    {
      fileMatch: ['^ci/applications-versions.yaml$'],
      matchStrings: ['(?<depName>[^\\s]+): (?<currentValue>[^\\s]+) # (?<datasource>[^\\s]+)'],
    },
    {
      fileMatch: ['^.github/workflows/main.yaml$'],
      matchStrings: ["node-version: '(?<currentValue>[^\\s]+).x'"],
      depNameTemplate: 'node',
      datasourceTemplate: 'node',
    },
  ],
  packageRules: [
    /** Automerge the patch, the minor and the dev dependency */
    {
      matchDepTypes: ['devDependencies'],
      automerge: true,
    },
    /** Group the patch and the minor */
    {
      matchUpdateTypes: ['patch'],
      groupName: 'all patch versions',
      automerge: true,
    },
    {
      matchUpdateTypes: ['minor'],
      groupName: 'all minor versions',
      automerge: true,
    },
    /** Accept only the patch on the stabilization branches */
    {
      matchBaseBranches: ['/2\\..*/'],
      matchUpdateTypes: ['major', 'minor', 'pin', 'digest', 'lockFileMaintenance', 'rollback', 'bump'],
      enabled: false,
    },
  ],
}

Add missing base branches in Renovate

{
  extends: ['config:base'],
  timezone: 'Europe/Zurich',
  schedule: 'after 1am on Saturday',
  labels: ['dependencies'],
  separateMajorMinor: true,
  separateMinorPatch: true,
  prHourlyLimit: 0,
  prConcurrentLimit: 0,
  lockFileMaintenance: {enabled: true, automerge: true},
  baseBranches: ['master', '2.7', '2.6', '2.4'],
  regexManagers: [
    {
      fileMatch: ['^ci/applications-versions.yaml$'],
      matchStrings: ['(?<depName>[^\\s]+): (?<currentValue>[^\\s]+) # (?<datasource>[^\\s]+)'],
    },
    {
      fileMatch: ['^.github/workflows/main.yaml$'],
      matchStrings: ["node-version: '(?<currentValue>[^\\s]+).x'"],
      depNameTemplate: 'node',
      datasourceTemplate: 'node',
    },
  ],
  packageRules: [
    /** Automerge the patch, the minor and the dev dependency */
    {
      matchDepTypes: ['devDependencies'],
      automerge: true,
    },
    /** Group the patch and the minor */
    {
      matchUpdateTypes: ['patch'],
      groupName: 'all patch versions',
      automerge: true,
    },
    {
      matchUpdateTypes: ['minor'],
      groupName: 'all minor versions',
      automerge: true,
    },
    /** Accept only the patch on the stabilization branches */
    {
      matchBaseBranches: ['/2\\..*/'],
      matchUpdateTypes: ['major', 'minor', 'pin', 'digest', 'lockFileMaintenance', 'rollback', 'bump'],
      enabled: false,
    },
  ],
}


{
  babelrc: false,
  comments: false,
  plugins: ['transform-export-extensions', 'transform-runtime'],
  // Order is important!
  presets: [
    ['env', {
      targets: { ie: '11' },
      useBuiltIns: true,
    }],
    'stage-2',
    'react',
    'flow',
  ],
}

Drop down to support IE 10.

{
  babelrc: false,
  comments: false,
  plugins: ['transform-export-extensions', 'transform-runtime'],
  // Order is important!
  presets: [
    ['env', {
      targets: { ie: '10' },
      useBuiltIns: true,
    }],
    'stage-2',
    'react',
    'flow',
  ],
}


{
  port: ":9091",
  prom_port: ":20000",
  pubsub_event_topic: "gold-skia-eventbus-sql-test-3",
  pubsub_project_id: "skia-public",

  ingestion_configs: {
    // Primary Ingester
    gold_sql: {
      backup_poll_every: "1h",
      backup_poll_last_n_commits: 5,
      backup_poll_last_n_hours: 2,
      gcs_sources: [
        {
          bucket: "skia-infra-gm",
          prefix: "dm-json-v1"
        }
      ],
      extra_configuration: {
        SQLConnectionURL: "postgresql://root@gold-cockroachdb-public:26234/demo_gold_db?sslmode=disable",
      }
    }
  }
}

Connect SQL to staging db

{
  port: ":9091",
  prom_port: ":20000",
  pubsub_event_topic: "gold-skia-eventbus-sql-test-3",
  pubsub_project_id: "skia-public",

  ingestion_configs: {
    // Primary Ingester
    gold_sql: {
      backup_poll_every: "1h",
      backup_poll_last_n_commits: 5,
      backup_poll_last_n_hours: 2,
      gcs_sources: [
        {
          bucket: "skia-infra-gm",
          prefix: "dm-json-v1"
        }
      ],
      extra_configuration: {
        SQLConnectionURL: "postgresql://root@gold-cockroachdb-public:26234/staging_db?sslmode=disable",
      }
    }
  }
}


{
    "BASELINE_SERVER_IMAGE": "gcr.io/skia-public/gold-baseline-server:2021-11-30T19_26_20Z-kjlubick-37a7dcb-clean",
    "DIFFCALCULATOR_IMAGE":  "gcr.io/skia-public/gold-diffcalculator:2021-11-30T19_26_37Z-kjlubick-37a7dcb-clean",
    "FRONTEND_IMAGE":        "gcr.io/skia-public/gold-frontend:2021-11-30T19_30_22Z-kjlubick-37a7dcb-clean",
    "GITILESFOLLOWER_IMAGE": "gcr.io/skia-public/gold-gitilesfollower:2021-11-30T19_31_28Z-kjlubick-37a7dcb-clean",
    "INGESTION_IMAGE":       "gcr.io/skia-public/gold-ingestion:2021-11-30T19_31_36Z-kjlubick-37a7dcb-clean",
    "PERIODICTASKS_IMAGE":   "gcr.io/skia-public/gold-periodictasks:2021-11-30T19_31_46Z-kjlubick-37a7dcb-clean",
}

Deploy baseline-server with improved hash cache

{
    "BASELINE_SERVER_IMAGE": "gcr.io/skia-public/gold-baseline-server:2021-12-15T20_33_49Z-kjlubick-bb31ccb-clean",
    "DIFFCALCULATOR_IMAGE":  "gcr.io/skia-public/gold-diffcalculator:2021-11-30T19_26_37Z-kjlubick-37a7dcb-clean",
    "FRONTEND_IMAGE":        "gcr.io/skia-public/gold-frontend:2021-11-30T19_30_22Z-kjlubick-37a7dcb-clean",
    "GITILESFOLLOWER_IMAGE": "gcr.io/skia-public/gold-gitilesfollower:2021-11-30T19_31_28Z-kjlubick-37a7dcb-clean",
    "INGESTION_IMAGE":       "gcr.io/skia-public/gold-ingestion:2021-11-30T19_31_36Z-kjlubick-37a7dcb-clean",
    "PERIODICTASKS_IMAGE":   "gcr.io/skia-public/gold-periodictasks:2021-11-30T19_31_46Z-kjlubick-37a7dcb-clean",
}


{
  authorized_users: [
    "google.com",
    "flutter-prod-builder@chops-service-accounts.iam.gserviceaccount.com",
    // Note: gmail accounts should be in "normalized" form, that is no dots and no pluses.
    "ianhickson@gmail.com",
    "lavidalovett@gmail.com",
  ],
  client_secret_file: "/etc/skia.org/login.json",
  frontend: {
    baseRepoURL: "<inherited from git_repo_url>",
    defaultCorpus: "flutter",
    title: "Flutter Gold",
  },
  prom_port: ":20000",
  ready_port: ":8000",
  resources_path: "/usr/local/share/frontend/dist",

  // These values affect the k8s deployment; they are not read in by the binary.
  K8S_CPU: 4,
  K8S_LOGIN_SECRETS: "skia-org-legacy-login-secrets",
  K8S_MEMORY: "4Gi",
}

Add service accounts to flutter's triage list

{
  authorized_users: [
    "google.com",
    "flutter-prod-builder@chops-service-accounts.iam.gserviceaccount.com",
    "flutter-staging-builder@chops-service-accounts.iam.gserviceaccount.com",
    "flutter-try-builder@chops-service-accounts.iam.gserviceaccount.com",
    // Note: gmail accounts should be in "normalized" form, that is no dots and no pluses.
    "ianhickson@gmail.com",
    "lavidalovett@gmail.com",
  ],
  client_secret_file: "/etc/skia.org/login.json",
  frontend: {
    baseRepoURL: "<inherited from git_repo_url>",
    defaultCorpus: "flutter",
    title: "Flutter Gold",
  },
  prom_port: ":20000",
  ready_port: ":8000",
  resources_path: "/usr/local/share/frontend/dist",

  // These values affect the k8s deployment; they are not read in by the binary.
  K8S_CPU: 4,
  K8S_LOGIN_SECRETS: "skia-org-legacy-login-secrets",
  K8S_MEMORY: "4Gi",
}