TEST_VM(LogDecorations, tags) { char expected_tags[1 * K]; tagset.label(expected_tags, sizeof(expected_tags)); // Verify that the expected tags are included in the tags decoration LogDecorations decorations(LogLevel::Info, tagset, default_decorators); EXPECT_STREQ(expected_tags, decorations.decoration(LogDecorators::tags_decorator)); }
// Test the pid and tid decorations TEST(LogDecorations, identifiers) { LogDecorators decorator_selection; ASSERT_TRUE(decorator_selection.parse("pid,tid")); LogDecorations decorations(LogLevel::Info, tagset, decorator_selection); struct { intx expected; LogDecorators::Decorator decorator; } ids[] = { { os::current_process_id(), LogDecorators::pid_decorator }, { os::current_thread_id(), LogDecorators::tid_decorator }, }; for (uint i = 0; i < ARRAY_SIZE(ids); i++) { const char* reported = decorations.decoration(ids[i].decorator); // Verify format const char* str; for (str = reported; isdigit(*str); str++) { // Skip over digits } EXPECT_EQ('\0', *str) << "Should only contain digits"; // Verify value EXPECT_EQ(ids[i].expected, strtol(reported, NULL, 10)); } }
// Test the time decoration TEST(LogDecorations, iso8601_time) { LogDecorators decorator_selection; ASSERT_TRUE(decorator_selection.parse("time")); LogDecorations decorations(LogLevel::Info, tagset, decorator_selection); const char *timestr = decorations.decoration(LogDecorators::time_decorator); time_t expected_ts = time(NULL); // Verify format int y, M, d, h, m; double s; int read = sscanf(timestr, "%d-%d-%dT%d:%d:%lf", &y, &M, &d, &h, &m, &s); ASSERT_EQ(6, read) << "Invalid format: " << timestr; // Verify reported time & date struct tm reported_time = {0}; reported_time.tm_year = y - 1900; reported_time.tm_mon = M - 1; reported_time.tm_mday = d; reported_time.tm_hour = h; reported_time.tm_min = m; reported_time.tm_sec = s; reported_time.tm_isdst = -1; // let mktime deduce DST settings time_t reported_ts = mktime(&reported_time); expected_ts = mktime(localtime(&expected_ts)); time_t diff = reported_ts - expected_ts; if (diff < 0) { diff = -diff; } // Allow up to 10 seconds in difference ASSERT_LE(diff, 10) << "Reported time: " << reported_ts << " (" << timestr << ")" << ", expected time: " << expected_ts; }
TEST_VM(LogDecorations, uptime) { // Verify the format of the decoration int a, b; char decimal_point; LogDecorations decorations(LogLevel::Info, tagset, default_decorators); const char* uptime = decorations.decoration(LogDecorators::uptime_decorator); int read = sscanf(uptime, "%d%c%ds", &a, &decimal_point, &b); EXPECT_EQ(3, read) << "Invalid uptime decoration: " << uptime; EXPECT_TRUE(decimal_point == '.' || decimal_point == ',') << "Invalid uptime decoration: " << uptime; // Verify that uptime increases double prev = 0; for (int i = 0; i < 3; i++) { os::naked_short_sleep(10); LogDecorations d(LogLevel::Info, tagset, default_decorators); double cur = strtod(d.decoration(LogDecorators::uptime_decorator), NULL); ASSERT_LT(prev, cur); prev = cur; } }
TEST_VM(LogDecorations, level) { for (uint l = LogLevel::First; l <= LogLevel::Last; l++) { LogLevelType level = static_cast<LogLevelType>(l); // Create a decorations object for the current level LogDecorations decorations(level, tagset, default_decorators); // Verify that the level decoration matches the specified level EXPECT_STREQ(LogLevel::name(level), decorations.decoration(LogDecorators::level_decorator)); // Test changing level after object creation time LogLevelType other_level; if (l != LogLevel::Last) { other_level = static_cast<LogLevelType>(l + 1); } else { other_level = static_cast<LogLevelType>(LogLevel::First); } decorations.set_level(other_level); EXPECT_STREQ(LogLevel::name(other_level), decorations.decoration(LogDecorators::level_decorator)) << "Decoration reports incorrect value after changing the level"; } }
// Test the utctime decoration TEST(LogDecorations, iso8601_utctime) { LogDecorators decorator_selection; ASSERT_TRUE(decorator_selection.parse("utctime")); LogDecorations decorations(LogLevel::Info, tagset, decorator_selection); const char *timestr = decorations.decoration(LogDecorators::utctime_decorator); time_t expected_ts = time(NULL); // Verify format char trailing_character; int y, M, d, h, m, offset; double s; int read = sscanf(timestr, "%d-%d-%dT%d:%d:%lf%c%d", &y, &M, &d, &h, &m, &s, &trailing_character, &offset); ASSERT_GT(read, 7) << "Invalid format: " << timestr; // Ensure time is UTC (no offset) if (trailing_character == '+') { ASSERT_EQ(0, offset) << "Invalid offset: " << timestr; } else { ASSERT_EQ('Z', trailing_character) << "Invalid offset: " << timestr; } struct tm reported_time = {0}; reported_time.tm_year = y - 1900; reported_time.tm_mon = M - 1; reported_time.tm_mday = d; reported_time.tm_hour = h; reported_time.tm_min = m; reported_time.tm_sec = s; reported_time.tm_isdst = 0; // No DST for UTC timestamps time_t reported_ts = mktime(&reported_time); expected_ts = mktime(gmtime(&expected_ts)); time_t diff = reported_ts - expected_ts; if (diff < 0) { diff = -diff; } // Allow up to 10 seconds in difference ASSERT_LE(diff, 10) << "Reported time: " << reported_ts << " (" << timestr << ")" << ", expected time: " << expected_ts; }
// Test each variation of the different timestamp decorations (ms, ns, uptime ms, uptime ns) TEST_VM(LogDecorations, timestamps) { struct { const LogDecorators::Decorator decorator; const char* suffix; } test_decorator[] = { { LogDecorators::timemillis_decorator, "ms" }, { LogDecorators::uptimemillis_decorator, "ms" }, { LogDecorators::timenanos_decorator, "ns" }, { LogDecorators::uptimenanos_decorator, "ns" } }; for (uint i = 0; i < ARRAY_SIZE(test_decorator); i++) { LogDecorators::Decorator decorator = test_decorator[i].decorator; LogDecorators decorator_selection; ASSERT_TRUE(decorator_selection.parse(LogDecorators::name(decorator))); // Create decorations with the decorator we want to test included LogDecorations decorations(LogLevel::Info, tagset, decorator_selection); const char* decoration = decorations.decoration(decorator); // Verify format of timestamp const char* suffix; for (suffix = decoration; isdigit(*suffix); suffix++) { // Skip over digits } EXPECT_STREQ(test_decorator[i].suffix, suffix); // Verify timestamp values julong prev = 0; for (int i = 0; i < 3; i++) { os::naked_short_sleep(5); LogDecorations d(LogLevel::Info, tagset, decorator_selection); julong val = strtoull(d.decoration(decorator), NULL, 10); ASSERT_LT(prev, val); prev = val; } } }
void GeoPolygonGraphicsItem::paint( GeoPainter* painter, const ViewportParams* viewport ) { painter->save(); bool const isBuildingFrame = isDecoration(); bool const isBuildingRoof = !isDecoration() && !decorations().isEmpty(); QPen currentPen = painter->pen(); if ( !style() ) { painter->setPen( QPen() ); } else { if ( !style()->polyStyle().outline() || isBuildingFrame ) { currentPen.setColor( Qt::transparent ); } else { if ( currentPen.color() != style()->lineStyle().paintedColor() || currentPen.widthF() != style()->lineStyle().width() ) { currentPen.setColor( style()->lineStyle().paintedColor() ); currentPen.setWidthF( style()->lineStyle().width() ); } if ( currentPen.capStyle() != style()->lineStyle().capStyle() ) currentPen.setCapStyle( style()->lineStyle().capStyle() ); if ( currentPen.style() != style()->lineStyle().penStyle() ) currentPen.setStyle( style()->lineStyle().penStyle() ); } if ( painter->pen() != currentPen ) painter->setPen( currentPen ); if ( !style()->polyStyle().fill() ) { if ( painter->brush().color() != Qt::transparent ) painter->setBrush( QColor( Qt::transparent ) ); } else { if ( isBuildingFrame ) { painter->setBrush( style()->polyStyle().paintedColor().darker(150) ); } else if ( painter->brush().color() != style()->polyStyle().paintedColor() ) { QImage textureImage = style()->polyStyle().textureImage(); if( !textureImage.isNull()){ GeoDataCoordinates coords = latLonAltBox().center(); qreal x, y; viewport->screenCoordinates(coords, x, y); if (m_cachedTexturePath != style()->polyStyle().texturePath() || m_cachedTextureColor != style()->polyStyle().paintedColor() ) { m_cachedTexture = QImage ( textureImage.size(), QImage::Format_ARGB32_Premultiplied ); m_cachedTexture.fill(style()->polyStyle().paintedColor()); QPainter imagePainter(&m_cachedTexture ); imagePainter.drawImage(0, 0, textureImage); imagePainter.end(); m_cachedTexturePath = style()->polyStyle().texturePath(); m_cachedTextureColor = style()->polyStyle().paintedColor(); } QBrush brush; brush.setTextureImage(m_cachedTexture); QTransform transform; brush.setTransform(transform.translate(x,y)); painter->setBrush(brush); } else { painter->setBrush( style()->polyStyle().paintedColor() ); } } } } if ( isBuildingFrame || isBuildingRoof ) { bool drawAccurate3D = false; bool isCameraAboveBuilding = false; QPointF offsetAtCorner = buildingOffset(QPointF(0, 0), viewport, &isCameraAboveBuilding); qreal maxOffset = qMax( qAbs( offsetAtCorner.x() ), qAbs( offsetAtCorner.y() ) ); drawAccurate3D = painter->mapQuality() == HighQuality ? maxOffset > 5.0 : maxOffset > 8.0; // Since subtracting one fully contained polygon from another results in a single // polygon with a "connecting line" between the inner and outer part we need // to first paint the inner area with no pen and then the outlines with the correct pen. QVector<QPolygonF*> outlines; QVector<QPolygonF*> innerPolygons; QVector<QPolygonF*> polygons; bool const hasInnerBoundaries = m_polygon ? !m_polygon->innerBoundaries().isEmpty() : false; if (m_polygon) { if (hasInnerBoundaries) { screenPolygons(viewport, m_polygon, innerPolygons, outlines); } viewport->screenCoordinates(m_polygon->outerBoundary(), polygons); } else if (m_ring) { viewport->screenCoordinates(*m_ring, polygons); } if ( isBuildingFrame ) { QVector<QPolygonF*> sides = (hasInnerBoundaries && drawAccurate3D && isCameraAboveBuilding) ? outlines : polygons; foreach(QPolygonF* polygon, sides) { if (polygon->isEmpty()) { continue; } if ( drawAccurate3D && isCameraAboveBuilding ) { // draw the building sides int const size = polygon->size(); QPointF & a = (*polygon)[0]; QPointF shiftA = a + buildingOffset(a, viewport); for (int i=1; i<size; ++i) { QPointF const & b = (*polygon)[i]; QPointF const shiftB = b + buildingOffset(b, viewport); QPolygonF buildingSide = QPolygonF() << a << shiftA << shiftB << b; if (hasInnerBoundaries) { //smoothen away our loss of antialiasing due to the QRegion Qt-bug workaround painter->setPen(QPen(painter->brush().color(), 1.5)); } painter->drawPolygon(buildingSide); a = b; shiftA = shiftB; } } else { // don't draw the building sides - just draw the base frame instead if (hasInnerBoundaries) { QRegion clip(polygon->toPolygon()); foreach(QPolygonF* clipPolygon, innerPolygons) { clip-=QRegion(clipPolygon->toPolygon()); } painter->setClipRegion(clip); } painter->drawPolygon(*polygon); } } } else if (isBuildingRoof) {
void LogTagSet::log(LogLevelType level, const char* msg) { LogDecorations decorations(level, *this, _decorators); for (LogOutputList::Iterator it = _output_list.iterator(level); it != _output_list.end(); it++) { (*it)->write(decorations, msg); } }