Iy0qLSBjb2Rpbmc6IElTTy04ODU5LTEgLSotCiMgcHlzcWxpdGUyL3Rlc3QvdHJhbnNhY3Rpb25zLnB5OiB0ZXN0cyB0cmFuc2FjdGlvbnMKIwojIENvcHlyaWdodCAoQykgMjAwNS0yMDA3IEdlcmhhcmQgSORyaW5nIDxnaEBnaGFlcmluZy5kZT4KIwojIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHB5c3FsaXRlLgojCiMgVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWQKIyB3YXJyYW50eS4gIEluIG5vIGV2ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBkYW1hZ2VzCiMgYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS4KIwojIFBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byBhbnlvbmUgdG8gdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLAojIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXQKIyBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6CiMKIyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdAojICAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlCiMgICAgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlCiMgICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC4KIyAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZQojICAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4KIyAzLiBUaGlzIG5vdGljZSBtYXkgbm90IGJlIHJlbW92ZWQgb3IgYWx0ZXJlZCBmcm9tIGFueSBzb3VyY2UgZGlzdHJpYnV0aW9uLgoKaW1wb3J0IG9zLCB1bml0dGVzdAppbXBvcnQgc3FsaXRlMyBhcyBzcWxpdGUKCmRlZiBnZXRfZGJfcGF0aCgpOgogICAgcmV0dXJuICJzcWxpdGVfdGVzdGRiIgoKY2xhc3MgVHJhbnNhY3Rpb25UZXN0cyh1bml0dGVzdC5UZXN0Q2FzZSk6CiAgICBkZWYgc2V0VXAoc2VsZik6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBvcy5yZW1vdmUoZ2V0X2RiX3BhdGgoKSkKICAgICAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICAgICAgcGFzcwoKICAgICAgICBzZWxmLmNvbjEgPSBzcWxpdGUuY29ubmVjdChnZXRfZGJfcGF0aCgpLCB0aW1lb3V0PTAuMSkKICAgICAgICBzZWxmLmN1cjEgPSBzZWxmLmNvbjEuY3Vyc29yKCkKCiAgICAgICAgc2VsZi5jb24yID0gc3FsaXRlLmNvbm5lY3QoZ2V0X2RiX3BhdGgoKSwgdGltZW91dD0wLjEpCiAgICAgICAgc2VsZi5jdXIyID0gc2VsZi5jb24yLmN1cnNvcigpCgogICAgZGVmIHRlYXJEb3duKHNlbGYpOgogICAgICAgIHNlbGYuY3VyMS5jbG9zZSgpCiAgICAgICAgc2VsZi5jb24xLmNsb3NlKCkKCiAgICAgICAgc2VsZi5jdXIyLmNsb3NlKCkKICAgICAgICBzZWxmLmNvbjIuY2xvc2UoKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIG9zLnVubGluayhnZXRfZGJfcGF0aCgpKQogICAgICAgIGV4Y2VwdCBPU0Vycm9yOgogICAgICAgICAgICBwYXNzCgogICAgZGVmIENoZWNrRE1MZG9lc0F1dG9Db21taXRCZWZvcmUoc2VsZik6CiAgICAgICAgc2VsZi5jdXIxLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSB0ZXN0KGkpIikKICAgICAgICBzZWxmLmN1cjEuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChpKSB2YWx1ZXMgKDUpIikKICAgICAgICBzZWxmLmN1cjEuZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIHRlc3QyKGopIikKICAgICAgICBzZWxmLmN1cjIuZXhlY3V0ZSgic2VsZWN0IGkgZnJvbSB0ZXN0IikKICAgICAgICByZXMgPSBzZWxmLmN1cjIuZmV0Y2hhbGwoKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKHJlcyksIDEpCgogICAgZGVmIENoZWNrSW5zZXJ0U3RhcnRzVHJhbnNhY3Rpb24oc2VsZik6CiAgICAgICAgc2VsZi5jdXIxLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSB0ZXN0KGkpIikKICAgICAgICBzZWxmLmN1cjEuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChpKSB2YWx1ZXMgKDUpIikKICAgICAgICBzZWxmLmN1cjIuZXhlY3V0ZSgic2VsZWN0IGkgZnJvbSB0ZXN0IikKICAgICAgICByZXMgPSBzZWxmLmN1cjIuZmV0Y2hhbGwoKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKHJlcyksIDApCgogICAgZGVmIENoZWNrVXBkYXRlU3RhcnRzVHJhbnNhY3Rpb24oc2VsZik6CiAgICAgICAgc2VsZi5jdXIxLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSB0ZXN0KGkpIikKICAgICAgICBzZWxmLmN1cjEuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChpKSB2YWx1ZXMgKDUpIikKICAgICAgICBzZWxmLmNvbjEuY29tbWl0KCkKICAgICAgICBzZWxmLmN1cjEuZXhlY3V0ZSgidXBkYXRlIHRlc3Qgc2V0IGk9NiIpCiAgICAgICAgc2VsZi5jdXIyLmV4ZWN1dGUoInNlbGVjdCBpIGZyb20gdGVzdCIpCiAgICAgICAgcmVzID0gc2VsZi5jdXIyLmZldGNob25lKClbMF0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlcywgNSkKCiAgICBkZWYgQ2hlY2tEZWxldGVTdGFydHNUcmFuc2FjdGlvbihzZWxmKToKICAgICAgICBzZWxmLmN1cjEuZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIHRlc3QoaSkiKQogICAgICAgIHNlbGYuY3VyMS5leGVjdXRlKCJpbnNlcnQgaW50byB0ZXN0KGkpIHZhbHVlcyAoNSkiKQogICAgICAgIHNlbGYuY29uMS5jb21taXQoKQogICAgICAgIHNlbGYuY3VyMS5leGVjdXRlKCJkZWxldGUgZnJvbSB0ZXN0IikKICAgICAgICBzZWxmLmN1cjIuZXhlY3V0ZSgic2VsZWN0IGkgZnJvbSB0ZXN0IikKICAgICAgICByZXMgPSBzZWxmLmN1cjIuZmV0Y2hhbGwoKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKHJlcyksIDEpCgogICAgZGVmIENoZWNrUmVwbGFjZVN0YXJ0c1RyYW5zYWN0aW9uKHNlbGYpOgogICAgICAgIHNlbGYuY3VyMS5leGVjdXRlKCJjcmVhdGUgdGFibGUgdGVzdChpKSIpCiAgICAgICAgc2VsZi5jdXIxLmV4ZWN1dGUoImluc2VydCBpbnRvIHRlc3QoaSkgdmFsdWVzICg1KSIpCiAgICAgICAgc2VsZi5jb24xLmNvbW1pdCgpCiAgICAgICAgc2VsZi5jdXIxLmV4ZWN1dGUoInJlcGxhY2UgaW50byB0ZXN0KGkpIHZhbHVlcyAoNikiKQogICAgICAgIHNlbGYuY3VyMi5leGVjdXRlKCJzZWxlY3QgaSBmcm9tIHRlc3QiKQogICAgICAgIHJlcyA9IHNlbGYuY3VyMi5mZXRjaGFsbCgpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4ocmVzKSwgMSkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlc1swXVswXSwgNSkKCiAgICBkZWYgQ2hlY2tUb2dnbGVBdXRvQ29tbWl0KHNlbGYpOgogICAgICAgIHNlbGYuY3VyMS5leGVjdXRlKCJjcmVhdGUgdGFibGUgdGVzdChpKSIpCiAgICAgICAgc2VsZi5jdXIxLmV4ZWN1dGUoImluc2VydCBpbnRvIHRlc3QoaSkgdmFsdWVzICg1KSIpCiAgICAgICAgc2VsZi5jb24xLmlzb2xhdGlvbl9sZXZlbCA9IE5vbmUKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHNlbGYuY29uMS5pc29sYXRpb25fbGV2ZWwsIE5vbmUpCiAgICAgICAgc2VsZi5jdXIyLmV4ZWN1dGUoInNlbGVjdCBpIGZyb20gdGVzdCIpCiAgICAgICAgcmVzID0gc2VsZi5jdXIyLmZldGNoYWxsKCkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihyZXMpLCAxKQoKICAgICAgICBzZWxmLmNvbjEuaXNvbGF0aW9uX2xldmVsID0gIkRFRkVSUkVEIgogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5jb24xLmlzb2xhdGlvbl9sZXZlbCAsICJERUZFUlJFRCIpCiAgICAgICAgc2VsZi5jdXIxLmV4ZWN1dGUoImluc2VydCBpbnRvIHRlc3QoaSkgdmFsdWVzICg1KSIpCiAgICAgICAgc2VsZi5jdXIyLmV4ZWN1dGUoInNlbGVjdCBpIGZyb20gdGVzdCIpCiAgICAgICAgcmVzID0gc2VsZi5jdXIyLmZldGNoYWxsKCkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihyZXMpLCAxKQoKICAgIGRlZiBDaGVja1JhaXNlVGltZW91dChzZWxmKToKICAgICAgICBpZiBzcWxpdGUuc3FsaXRlX3ZlcnNpb25faW5mbyA8ICgzLCAyLCAyKToKICAgICAgICAgICAgIyBUaGlzIHdpbGwgZmFpbCAoaGFuZykgb24gZWFybGllciB2ZXJzaW9ucyBvZiBzcWxpdGUuCiAgICAgICAgICAgICMgRGV0ZXJtaW5lIGV4YWN0IHZlcnNpb24gaXQgd2FzIGZpeGVkLiAzLjIuMSBoYW5ncy4KICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgc2VsZi5jdXIxLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSB0ZXN0KGkpIikKICAgICAgICBzZWxmLmN1cjEuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChpKSB2YWx1ZXMgKDUpIikKICAgICAgICB0cnk6CiAgICAgICAgICAgIHNlbGYuY3VyMi5leGVjdXRlKCJpbnNlcnQgaW50byB0ZXN0KGkpIHZhbHVlcyAoNSkiKQogICAgICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBhbiBPcGVyYXRpb25hbEVycm9yIikKICAgICAgICBleGNlcHQgc3FsaXRlLk9wZXJhdGlvbmFsRXJyb3I6CiAgICAgICAgICAgIHBhc3MKICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgIHNlbGYuZmFpbCgic2hvdWxkIGhhdmUgcmFpc2VkIGFuIE9wZXJhdGlvbmFsRXJyb3IiKQoKICAgIGRlZiBDaGVja0xvY2tpbmcoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVGhpcyB0ZXN0cyB0aGUgaW1wcm92ZWQgY29uY3VycmVuY3kgd2l0aCBweXNxbGl0ZSAyLjMuNC4gWW91IG5lZWRlZAogICAgICAgIHRvIHJvbGwgYmFjayBjb24yIGJlZm9yZSB5b3UgY291bGQgY29tbWl0IGNvbjEuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc3FsaXRlLnNxbGl0ZV92ZXJzaW9uX2luZm8gPCAoMywgMiwgMik6CiAgICAgICAgICAgICMgVGhpcyB3aWxsIGZhaWwgKGhhbmcpIG9uIGVhcmxpZXIgdmVyc2lvbnMgb2Ygc3FsaXRlLgogICAgICAgICAgICAjIERldGVybWluZSBleGFjdCB2ZXJzaW9uIGl0IHdhcyBmaXhlZC4gMy4yLjEgaGFuZ3MuCiAgICAgICAgICAgIHJldHVybgogICAgICAgIHNlbGYuY3VyMS5leGVjdXRlKCJjcmVhdGUgdGFibGUgdGVzdChpKSIpCiAgICAgICAgc2VsZi5jdXIxLmV4ZWN1dGUoImluc2VydCBpbnRvIHRlc3QoaSkgdmFsdWVzICg1KSIpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBzZWxmLmN1cjIuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChpKSB2YWx1ZXMgKDUpIikKICAgICAgICAgICAgc2VsZi5mYWlsKCJzaG91bGQgaGF2ZSByYWlzZWQgYW4gT3BlcmF0aW9uYWxFcnJvciIpCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5PcGVyYXRpb25hbEVycm9yOgogICAgICAgICAgICBwYXNzCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBhbiBPcGVyYXRpb25hbEVycm9yIikKICAgICAgICAjIE5PIHNlbGYuY29uMi5yb2xsYmFjaygpIEhFUkUhISEKICAgICAgICBzZWxmLmNvbjEuY29tbWl0KCkKCiAgICBkZWYgQ2hlY2tSb2xsYmFja0N1cnNvckNvbnNpc3RlbmN5KHNlbGYpOgogICAgICAgICIiIgogICAgICAgIENoZWNrcyBpZiBjdXJzb3JzIG9uIHRoZSBjb25uZWN0aW9uIGFyZSBzZXQgaW50byBhICJyZXNldCIgc3RhdGUKICAgICAgICB3aGVuIGEgcm9sbGJhY2sgaXMgZG9uZSBvbiB0aGUgY29ubmVjdGlvbi4KICAgICAgICAiIiIKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIGN1ciA9IGNvbi5jdXJzb3IoKQogICAgICAgIGN1ci5leGVjdXRlKCJjcmVhdGUgdGFibGUgdGVzdCh4KSIpCiAgICAgICAgY3VyLmV4ZWN1dGUoImluc2VydCBpbnRvIHRlc3QoeCkgdmFsdWVzICg1KSIpCiAgICAgICAgY3VyLmV4ZWN1dGUoInNlbGVjdCAxIHVuaW9uIHNlbGVjdCAyIHVuaW9uIHNlbGVjdCAzIikKCiAgICAgICAgY29uLnJvbGxiYWNrKCkKICAgICAgICB0cnk6CiAgICAgICAgICAgIGN1ci5mZXRjaGFsbCgpCiAgICAgICAgICAgIHNlbGYuZmFpbCgiSW50ZXJmYWNlRXJyb3Igc2hvdWxkIGhhdmUgYmVlbiByYWlzZWQiKQogICAgICAgIGV4Y2VwdCBzcWxpdGUuSW50ZXJmYWNlRXJyb3IgYXMgZToKICAgICAgICAgICAgcGFzcwogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgc2VsZi5mYWlsKCJJbnRlcmZhY2VFcnJvciBzaG91bGQgaGF2ZSBiZWVuIHJhaXNlZCIpCgpjbGFzcyBTcGVjaWFsQ29tbWFuZFRlc3RzKHVuaXR0ZXN0LlRlc3RDYXNlKToKICAgIGRlZiBzZXRVcChzZWxmKToKICAgICAgICBzZWxmLmNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgc2VsZi5jdXIgPSBzZWxmLmNvbi5jdXJzb3IoKQoKICAgIGRlZiBDaGVja1ZhY3V1bShzZWxmKToKICAgICAgICBzZWxmLmN1ci5leGVjdXRlKCJjcmVhdGUgdGFibGUgdGVzdChpKSIpCiAgICAgICAgc2VsZi5jdXIuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChpKSB2YWx1ZXMgKDUpIikKICAgICAgICBzZWxmLmN1ci5leGVjdXRlKCJ2YWN1dW0iKQoKICAgIGRlZiBDaGVja0Ryb3BUYWJsZShzZWxmKToKICAgICAgICBzZWxmLmN1ci5leGVjdXRlKCJjcmVhdGUgdGFibGUgdGVzdChpKSIpCiAgICAgICAgc2VsZi5jdXIuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChpKSB2YWx1ZXMgKDUpIikKICAgICAgICBzZWxmLmN1ci5leGVjdXRlKCJkcm9wIHRhYmxlIHRlc3QiKQoKICAgIGRlZiBDaGVja1ByYWdtYShzZWxmKToKICAgICAgICBzZWxmLmN1ci5leGVjdXRlKCJjcmVhdGUgdGFibGUgdGVzdChpKSIpCiAgICAgICAgc2VsZi5jdXIuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChpKSB2YWx1ZXMgKDUpIikKICAgICAgICBzZWxmLmN1ci5leGVjdXRlKCJwcmFnbWEgY291bnRfY2hhbmdlcz0xIikKCiAgICBkZWYgdGVhckRvd24oc2VsZik6CiAgICAgICAgc2VsZi5jdXIuY2xvc2UoKQogICAgICAgIHNlbGYuY29uLmNsb3NlKCkKCmRlZiBzdWl0ZSgpOgogICAgZGVmYXVsdF9zdWl0ZSA9IHVuaXR0ZXN0Lm1ha2VTdWl0ZShUcmFuc2FjdGlvblRlc3RzLCAiQ2hlY2siKQogICAgc3BlY2lhbF9jb21tYW5kX3N1aXRlID0gdW5pdHRlc3QubWFrZVN1aXRlKFNwZWNpYWxDb21tYW5kVGVzdHMsICJDaGVjayIpCiAgICByZXR1cm4gdW5pdHRlc3QuVGVzdFN1aXRlKChkZWZhdWx0X3N1aXRlLCBzcGVjaWFsX2NvbW1hbmRfc3VpdGUpKQoKZGVmIHRlc3QoKToKICAgIHJ1bm5lciA9IHVuaXR0ZXN0LlRleHRUZXN0UnVubmVyKCkKICAgIHJ1bm5lci5ydW4oc3VpdGUoKSkKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICB0ZXN0KCkK