text:
package voicesplitting.gui;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;

import voicesplitting.utils.MidiNote;

/**
 * A NoteDisplayer is the JPanel that is able to display {@link MidiNote}s
 * graphically.
 *

 * It handles voice solos, note highlights, and note right click actions from the
 * {@link MidiNoteGUIPopupMenu} class.
 *
 * @author Andrew McLeod - 17 June, 2015
 * @version 1.0
 * @since 1.0
 */
public class NoteDisplayer extends JPanel {

	/**
	 *
	 */
	private static final long serialVersionUID = -8178173777771945115L;

	/**
	 * The column header to use for the JScrollPane, saved as a field so we can just repaint it from
	 * this class.
	 */
	private JPanel columnHeader;

	/**
	 * The row header to use for the JScrollPane, saved as a field so we can just repaint it from
	 * this class.
	 */
	private JPanel rowHeader;

	/**
	 * The horizontal scale of this GUI object. Note times will be divided by this amount to get layout
	 * location. Default is 10000.
	 */
	private int horizontalScale;

	/**
	 * The vertical scale of this GUI object. Note pitches will be multiplied by this amount to get layout
	 * location. Default is 10.
	 */
	private int verticalScale;

	/**
	 * The offset tick of the last {@link MidiNote} in the currently loaded MIDI.
	 */
	private long lastOffset = 0;

	/**
	 * Whether this is displaying voices or not.
	 */
	private boolean voices = false;

	/**
	 * A Set of the currently highlighted notes.
	 */
	private Set<MidiNoteGUI> highlightedNotes;

	/**
	 * The most recently clicked note.
	 */
	private MidiNoteGUI lastClicked;

	/**
	 * A Set of the currently soloed channels.
	 */
	private Set<Integer> soloedChannels;

	/**
	 * Create a new default NoteDisplayer with {@link #horizontalScale} 10000 and
	 * {@link #verticalScale} 10.
	 */
	public NoteDisplayer() {
		this(10000, 10);
	}

	/**
	 * Create a new NoteDisplayer with the given scale values.
	 *
	 * @param horizontalScale {@link #horizontalScale}
	 * @param verticalScale {@link #verticalScale}
	 */
	public NoteDisplayer(int horizontalScale, int verticalScale) {
		this.horizontalScale = Math.max(horizontalScale, GUIConstants.HORIZONTAL_SCALE_MIN);
		this.verticalScale = Math.max(verticalScale, GUIConstants.VERTICAL_SCALE_MIN);

		setLayout(null);
		setBackground(Color.DARK_GRAY);
		setPreferredSize(new Dimension(getDesiredWidth(), getDesiredHeight()));

		columnHeader = new JPanel(null);
		rowHeader = new JPanel(null);

		updateColumnHeaderView();
		updateRowHeaderView();

		ToolTipManager.sharedInstance().setInitialDelay(200);
		ToolTipManager.sharedInstance().setDismissDelay(Integer.MAX_VALUE);

		highlightedNotes = new HashSet<MidiNoteGUI>();
		soloedChannels = new HashSet<Integer>();

		addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (e.getButton() == MouseEvent.BUTTON1) {
					if (!e.isControlDown() && !e.isShiftDown()) {
						clearAllHighlights();
						setLastClicked(null);
					}

				} else if (e.getButton() == MouseEvent.BUTTON3) {
					MidiNoteGUIPopupMenu menu = new MidiNoteGUIPopupMenu(NoteDisplayer.this);
					menu.show(NoteDisplayer.this, e.getX(), e.getY());
				}
			}
		});
	}

	/**
	 * Paint this NoteDisplayer. This method is overridden in order to draw the lines for the
	 * grid.
	 *
	 * @param g The Graphics object which we will use to paint the NoteDisplayer.
	 */
	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		Graphics2D g2 = (Graphics2D) g;
		g2.setPaint(Color.GRAY);

		for (int i = 1; i < 128; i++) {
			int y = i * verticalScale;
			g2.drawLine(0, y, getDesiredWidth(), y);
		}

		double tickTime = getTickTime();

		for (double i = tickTime; (int) ((i * 1000000) / horizontalScale) + 10 < getDesiredWidth(); i += tickTime) {
			int x = (int) ((i * 1000000) / horizontalScale);
			g2.drawLine(x, 0, x, getDesiredHeight());
		}
	}

	/**
	 * Update and repaint the {@link #columnHeader}.
	 */
	public void updateColumnHeaderView() {
		columnHeader.removeAll();
		columnHeader.setBackground(Color.BLACK);
		columnHeader.setPreferredSize(new Dimension(getDesiredWidth(), GUIConstants.SCALE_SIZE));

		double tickTime = getTickTime();

		for (double i = tickTime; (int) ((i * 1000000) / horizontalScale) + 10 < getDesiredWidth(); i += tickTime) {
			BigDecimal bd = new BigDecimal(i);
		    bd = bd.setScale(2, RoundingMode.HALF_UP);

		    JLabel label = new JLabel(bd.toString());
		    label.setVerticalAlignment(SwingConstants.BOTTOM);
			label.setForeground(Color.WHITE);
			int width = label.getPreferredSize().width;
			label.setBounds((int) ((i * 1000000) / horizontalScale) - width / 2, 0, width, GUIConstants.SCALE_SIZE - 2);
			columnHeader.add(label);
		}
	}

	/**
	 * Get the time difference we should have between column ticks, in seconds. This will
	 * ensure that we have proper spacing in between ticks.
	 *
	 * @return The time difference in seconds.
	 */
	private double getTickTime() {
		double time = 1.;

		while ((time * 1000000.) / horizontalScale > 100) {
			time /= 2.;
		}

		while ((time * 1000000.) / horizontalScale < 50) {
			time *= 2.;
		}

		return time;
	}

	/**
	 * Update and repaint the {@link #rowHeader}.
	 */
	public void updateRowHeaderView() {
		rowHeader.removeAll();
		rowHeader.setBackground(Color.BLACK);
		rowHeader.setPreferredSize(new Dimension(GUIConstants.SCALE_SIZE, getDesiredHeight()));

		for (int i = 5; i < 128; i+= 5) {
			JLabel label = new JLabel(((Integer) i).toString(), SwingConstants.RIGHT);
			label.setForeground(Color.WHITE);
			int height = label.getPreferredSize().height;
			label.setBounds(0, (127 - i) * verticalScale + verticalScale / 2 - height / 2 + 1, GUIConstants.SCALE_SIZE - 2, height);
			rowHeader.add(label);
		}
	}

	/**
	 * Change the vertical scaling if we can (ie it doesn't get too far in or out).
	 *
	 * @param direction Zoom amount. A negative number indicates zoom out. Positive means zoom in.
	 */
	public void zoomVertical(int direction) {
		int priorLocation = ((JScrollPane) getParent().getParent()).getVerticalScrollBar().getValue();
		int priorHeight = getDesiredHeight();
		double priorPercentage = (double) priorLocation / (double) priorHeight;

		if (direction > 0) {
			verticalScale++;

		} else if (direction < 0 && verticalScale > GUIConstants.VERTICAL_SCALE_MIN) {
			verticalScale--;

		} else {
			// No scaling happened. We can skip the repainting.
			return;
		}

		updateRowHeaderView();
		refresh();

		int newHeight = getDesiredHeight();
		((JScrollPane) getParent().getParent()).getVerticalScrollBar().setValue((int) (priorPercentage * newHeight));
	}

	/**
	 * Change the horizontal scaling if we can (ie it doesn't get too far in or out).
	 *
	 * @param direction Zoom amount. A negative number indicates zoom out. Positive means zoom in.
	 */
	public void zoomHorizontal(int direction) {
		int priorLocation = ((JScrollPane) getParent().getParent()).getHorizontalScrollBar().getValue();
		int priorWidth = getDesiredWidth();
		double priorPercentage = (double) priorLocation / (double) priorWidth;

		if (direction > 0 && horizontalScale > 1000) {
			horizontalScale -= 1000;

		} else if (direction > 0 && horizontalScale > GUIConstants.HORIZONTAL_SCALE_MIN) {
			horizontalScale /= 2;

		} else if (direction < 0 && horizontalScale < 1000) {
			horizontalScale *= 2;

		} else if (direction < 0) {
			horizontalScale += 1000;

		} else {
			// No scaling happened. We can skip the repainting.
			return;
		}

		updateColumnHeaderView();
		refresh();

		int newWidth = getDesiredWidth();
		((JScrollPane) getParent().getParent()).getHorizontalScrollBar().setValue((int) (priorPercentage * newWidth));
	}

	/**
	 * Get the column header to use for the JScrollPane.
	 *
	 * @return {@link #columnHeader}
	 */
	public Component getColumnHeaderView() {
		return columnHeader;
	}

	/**
	 * Get the row header to use for the JScrollPane.
	 *
	 * @return {@link #rowHeader}
	 */
	public Component getRowHeaderView() {
		return rowHeader;
	}

	/**
	 * Get the desired width of this JPanel based on the last offset and the horizontal scale.
	 *
	 * @return The desired width of this JPanel
	 */
	public int getDesiredWidth() {
		return Math.max(1000, (int) (lastOffset / horizontalScale + 10));
	}

	/**
	 * Get the desired height of this JPanel based on the vertical scale.
	 *
	 * @return The desired height of this JPanel
	 */
	public int getDesiredHeight() {
		return 128 * verticalScale;
	}

	/**
	 * Revalidate and redraw this JPanel, including children. This also updates the preferred size.
	 */
	private void refresh() {
		setPreferredSize(new Dimension(getDesiredWidth(), getDesiredHeight()));

		for (Component component : this.getComponents()) {
			if (component instanceof MidiNoteGUI) {
				((MidiNoteGUI) component).setScale(horizontalScale, verticalScale);
			}
		}

		columnHeader.repaint();
		rowHeader.repaint();
		revalidate();
		repaint();
	}

	/**
	 * Set a new vertical and horizontal scale, and refresh if the values changed.
	 *
	 * @param horizontal {@link #horizontalScale}
	 * @param vertical {@link #verticalScale}
	 */
	public void setScale(int horizontal, int vertical) {
		boolean change = false;

		if (horizontalScale != horizontal) {
			horizontalScale = horizontal;
			change = true;
		}

		if (verticalScale != vertical) {
			verticalScale = vertical;
			change = true;
		}

		if (change) {
			refresh();
		}
	}

	/**
	 * Get the current horizontal scale.
	 *
	 * @return {@link #horizontalScale}
	 */
	public int getHorizontalScale() {
		return horizontalScale;
	}

	/**
	 * Get the current vertical scale.
	 *
	 * @return {@link #verticalScale}
	 */
	public int getVerticalScale() {
		return verticalScale;
	}

	/**
	 * Set the last offset to the given value.
	 *
	 * @param lastOffset {@link #lastOffset}
	 */
	public void setLastOffset(long lastOffset) {
		this.lastOffset = lastOffset;
	}

	/**
	 * Get whether this is displaying voices or not.
	 *
	 * @return {@link #voices}
	 */
	public boolean isVoices() {
		return voices;
	}

	/**
	 * Set whether this is displaying voices or not.
	 *
	 * @param voices {@link #voices}
	 */
	public void setVoices(boolean voices) {
		this.voices = voices;

		for (Component component : this.getComponents()) {
			if (component instanceof MidiNoteGUI) {
				MidiNoteGUI note = (MidiNoteGUI) component;

				note.updateBorder();
			}
		}
	}

	/**
	 * Unhighlight all notes currently highlighted.
	 */
	public void clearAllHighlights() {
		for (MidiNoteGUI note : highlightedNotes) {
			note.setHighlighted(false);
		}

		highlightedNotes.clear();
	}

	/**
	 * Get the last clicked note in this gui.
	 *
	 * @return {@link #lastClicked}
	 */
	public MidiNoteGUI getLastClicked() {
		return lastClicked;
	}

	/**
	 * Set the last clicked note to a new value.
	 *
	 * @param note {@link #lastClicked}
	 */
	public void setLastClicked(MidiNoteGUI note) {
		lastClicked = note;
	}

	/**
	 * Return whether we have highlighted notes or not.
	 *
	 * @return True if we have highlighted notes. False otherwise.
	 */
	public boolean hasHighlightedNotes() {
		return !highlightedNotes.isEmpty();
	}

	/**
	 * Toggle the highlighting of the given note.
	 *
	 * @param note The note whose highlighting we want to toggle.
	 */
	public void toggleHighlight(MidiNoteGUI note) {
		if (highlightedNotes.remove(note)) {
			note.setHighlighted(false);

		} else {
			highlightedNotes.add(note);
			note.setHighlighted(true);
		}
	}

	/**
	 * Change the channel of the highlighted notes to the given value.
	 *
	 * @param channel The channel we want to change the notes to.
	 */
	public void changeHighlightedChannels(int channel) {
		VoiceSplittingGUI gui = (VoiceSplittingGUI) SwingUtilities.getWindowAncestor(this);
		List<List<MidiNote>> gS = gui.getRunner().getGoldStandardVoices();
		while (gS.size() <= channel) {
			gS.add(new ArrayList<MidiNote>());
		}

		boolean visible = soloedChannels.isEmpty() || soloedChannels.contains(channel);
		for (MidiNoteGUI noteGui : highlightedNotes) {
			MidiNote note = noteGui.getNote();

			gS.get(note.getCorrectVoice()).remove(note);

			List<MidiNote> goldVoice = gS.get(channel);
			int index = 0;
			while (index < goldVoice.size() && note.compareTo(goldVoice.get(index)) > 0) {
				index++;
			}
			goldVoice.add(index, note);

			note.setCorrectVoice(channel);

			noteGui.setBackground(MidiNoteGUI.getColor(channel));
			noteGui.updateBorder();
			noteGui.setVisible(visible);
		}

		for (int i = gS.size() - 1; i >= 0 && gS.get(i).isEmpty(); i--) {
			gS.remove(i);
		}
	}

	/**
	 * Highlight all notes between the given 2 notes, inclusive. That is, all notes whose onsets and
	 * pitches are between or equal to those of either of the 2 notes.
	 *
	 * @param note1 The first boundary
	 * @param note2 The second boundary
	 */
	public void highlightAllBetween(MidiNoteGUI note1, MidiNoteGUI note2) {
		long minOnset = Math.min(note1.getNote().getOnsetTick(), note2.getNote().getOnsetTick());
		long maxOnset = Math.max(note1.getNote().getOnsetTick(), note2.getNote().getOnsetTick());
		long minPitch = Math.min(note1.getNote().getPitch(), note2.getNote().getPitch());
		long maxPitch = Math.max(note1.getNote().getPitch(), note2.getNote().getPitch());

		for (Component component : this.getComponents()) {
			if (component instanceof MidiNoteGUI) {
				MidiNoteGUI note = (MidiNoteGUI) component;

				if (!note.isHighlighted() && note.isVisible() &&
						note.getNote().getOnsetTick() >= minOnset && note.getNote().getOnsetTick() <= maxOnset &&
						note.getNote().getPitch() >= minPitch && note.getNote().getPitch() <= maxPitch) {

					toggleHighlight(note);
				}
			}
		}
	}

	/**
	 * Delete all of the currently highlighted notes.
	 */
	public void deleteHighlightedNotes() {
		VoiceSplittingGUI gui = (VoiceSplittingGUI) SwingUtilities.getWindowAncestor(this);

		for (MidiNoteGUI noteGui : highlightedNotes) {
			remove(noteGui);

			MidiNote note = noteGui.getNote();
			gui.getRunner().getNlg().getNoteList().remove(note);
			gui.getRunner().getGoldStandardVoices().get(note.getCorrectVoice()).remove(note);
		}

		highlightedNotes.clear();
		lastClicked = null;

		refresh();
	}

	/**
	 * Return if the given note is highlighted or not.
	 *
	 * @param note The note we are checking if it is highlighted.
	 * @return True if the given note is highlighted. False otherwise.
	 */
	public boolean isHighlighted(MidiNoteGUI note) {
		return highlightedNotes.contains(note);
	}

	/**
	 * Toggle the soloing of the given channel.
	 *
	 * @param channel The index of the channel to solo.
	 */
	public void toggleSolo(int channel) {
		if (soloedChannels.add(channel)) {
			// This channel was not yet soloed

			if (soloedChannels.size() == 1) {
				// This is the first soloed channel - remove all other notes
				for (Component comp : getComponents()) {
					if (comp instanceof MidiNoteGUI && ((MidiNoteGUI) comp).getNote().getCorrectVoice() != channel) {
						comp.setVisible(false);
					}
				}

			} else {
				// There are other channels soloed already - make this track's notes visible
				for (Component comp : getComponents()) {
					if (comp instanceof MidiNoteGUI && ((MidiNoteGUI) comp).getNote().getCorrectVoice() == channel) {
						comp.setVisible(true);
					}
				}
			}

		} else {
			// This channel was already soloed

			if (soloedChannels.size() == 1) {
				// This channel was the only one soloed - clear all
				clearAllSolos();

			} else {
				// There are others still soloed - hide this channel's notes
				soloedChannels.remove(channel);
				for (Component comp : getComponents()) {
					if (comp instanceof MidiNoteGUI && ((MidiNoteGUI) comp).getNote().getCorrectVoice() == channel) {
						comp.setVisible(false);
					}
				}
			}
		}
	}

	/**
	 * Clear all soloed channels. That is, make all notes visible.
	 */
	public void clearAllSolos() {
		if (!soloedChannels.isEmpty()) {
			// There were soloed tracks
			for (Component comp : getComponents()) {
				if (comp instanceof MidiNoteGUI) {
					comp.setVisible(true);
				}
			}

			soloedChannels.clear();
		}
	}

	/**
	 * Return if the given channel is soloed or not.
	 *
	 * @param channel The channel we want to check.
	 * @return True if the channel is currently soloed. False otherwise.
	 */
	public boolean isSoloed(int channel) {
		return soloedChannels.contains(channel);
	}

	/**
	 * Split the selected notes. This must be run when the only curently highlighted notes are exactly 2 that overlap.
	 * The split method simply switches the onset times of the 2 notes.
	 */
	public void splitHighlightedNotes() {
		if (highlightedNotes.size() != 2) {
			return;
		}

		// Get the 2 notes
		MidiNote note1 = null;
		MidiNoteGUI gui1 = null;
		MidiNote note2 = null;
		MidiNoteGUI gui2 = null;
		for (MidiNoteGUI note : highlightedNotes) {
			if (note1 == null) {
				note1 = note.getNote();
				gui1 = note;
			} else {
				note2 = note.getNote();
				gui2 = note;
			}
		}

		if (!note1.overlaps(note2)) {
			return;
		}

		long offsetTime = note1.getOffsetTime();
		long offsetTick = note1.getOffsetTick();

		note1.setOffset(note2.getOffsetTime(), note2.getOffsetTick());
		note2.setOffset(offsetTime, offsetTick);

		gui1.setScale(getHorizontalScale(), getVerticalScale());
		gui2.setScale(getHorizontalScale(), getVerticalScale());
	}

	/**
	 * Decide if we can split the currently highlighted notes or not. We can split if and only if
	 * there are exactly 2 notes highlighted and they overlap.
	 *
	 * @return True if we can split. False otherwise.
	 */
	public boolean canSplit() {
		if (highlightedNotes.size() != 2) {
			return false;
		}

		MidiNote note1 = null;
		MidiNote note2 = null;
		for (MidiNoteGUI note : highlightedNotes) {
			if (note1 == null) {
				note1 = note.getNote();

			} else {
				note2 = note.getNote();
			}
		}

		return note1.overlaps(note2);
	}
}


text:
package com.raphfrk.bukkit.serverportsimpleportal;

import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

public class SetPortalCommand implements CommandExecutor {

	SimplePortal p;

	public SetPortalCommand(SimplePortal p) {
		this.p = p;
	}

	@Override
	public boolean onCommand(CommandSender sender, Command command, String label,
			String[] args) {

		if (!sender.isOp()) {
			sender.sendMessage("[SimplePortal] Only ops may use this command");
			return true;
		}

		if(args.length != 1) {
			return false;
		}

		if (!(sender instanceof Player)) {
			sender.sendMessage("[SimplePortal] Only players can set portal locations");
			return true;
		}

		Player player = (Player)sender;

		IntLocation source = new IntLocation(player.getLocation());

		String target = args[0];

		try {
			new ServerPortLocationMirror(target);
		} catch (IllegalArgumentException iae) {
			sender.sendMessage("[SimplePortal] Unable to parse target location");
			return true;
		}

		p.portalManager.portals.put(source, target);

		sender.sendMessage("[SimplePortal] added link");
		sender.sendMessage("FROM: " + source);
		sender.sendMessage("TO: " + target);

		p.portalManager.writePortals();

		return true;

	}

}

redpajama_set_name: RedPajamaGithub


text:
package reads

import (
	"context"

	"github.com/gogo/protobuf/proto"
	"github.com/influxdata/influxdb/v2/models"
	"github.com/influxdata/influxdb/v2/storage/reads/datatypes"
	"github.com/influxdata/influxdb/v2/tsdb/cursors"
)

type ResultSet interface {
	// Next advances the ResultSet to the next cursor. It returns false
	// when there are no more cursors.
	Next() bool

	// Cursor returns the most recent cursor after a call to Next.
	Cursor() cursors.Cursor

	// Tags returns the tags for the most recent cursor after a call to Next.
	Tags() models.Tags

	// Close releases any resources allocated by the ResultSet.
	Close()

	// Err returns the first error encountered by the ResultSet.
	Err() error

	Stats() cursors.CursorStats
}

type GroupResultSet interface {
	// Next advances the GroupResultSet and returns the next GroupCursor. It
	// returns nil if there are no more groups.
	Next() GroupCursor

	// Close releases any resources allocated by the GroupResultSet.
	Close()

	// Err returns the first error encountered by the GroupResultSet.
	Err() error
}

type GroupCursor interface {
	// Next advances to the next cursor. Next will return false when there are no
	// more cursors in the current group.
	Next() bool

	// Cursor returns the most recent cursor after a call to Next.
	Cursor() cursors.Cursor

	// Tags returns the tags for the most recent cursor after a call to Next.
	Tags() models.Tags

	// Keys returns the union of all tag key names for all series produced by
	// this GroupCursor.
	Keys() [][]byte

	// PartitionKeyVals returns the values of all tags identified by the
	// keys specified in ReadRequest#GroupKeys. The tag values values will
	// appear in the same order as the GroupKeys.
	//
	// When the datatypes.GroupNone strategy is specified, PartitionKeyVals will
	// be nil.
	PartitionKeyVals() [][]byte

	// Close releases any resources allocated by the GroupCursor.
	Close()

	// Err returns the first error encountered by the GroupCursor.
	Err() error

	Stats() cursors.CursorStats

	Aggregate() *datatypes.Aggregate
}

type Store interface {
	ReadFilter(ctx context.Context, req *datatypes.ReadFilterRequest) (ResultSet, error)
	ReadGroup(ctx context.Context, req *datatypes.ReadGroupRequest) (GroupResultSet, error)
	// WindowAggregate will invoke a ReadWindowAggregateRequest against the Store.
	WindowAggregate(ctx context.Context, req *datatypes.ReadWindowAggregateRequest) (ResultSet, error)

	TagKeys(ctx context.Context, req *datatypes.TagKeysRequest) (cursors.StringIterator, error)
	TagValues(ctx context.Context, req *datatypes.TagValuesRequest) (cursors.StringIterator, error)

	ReadSeriesCardinality(ctx context.Context, req *datatypes.ReadSeriesCardinalityRequest) (cursors.Int64Iterator, error)
	SupportReadSeriesCardinality(ctx context.Context) bool

	GetSource(orgID, bucketID uint64) proto.Message
}


text:
#pragma once

#include <functional>

#include "envoy/api/v2/lds.pb.h"
#include "envoy/config/subscription.h"
#include "envoy/init/init.h"
#include "envoy/server/listener_manager.h"

#include "common/common/logger.h"

namespace Envoy {
namespace Server {

/**
 * LDS API implementation that fetches via Subscription.
 */
class LdsApiImpl : public LdsApi,
                   public Init::Target,
                   Config::SubscriptionCallbacks<envoy::api::v2::Listener>,
                   Logger::Loggable<Logger::Id::upstream> {
public:
  LdsApiImpl(const envoy::api::v2::core::ConfigSource& lds_config, Upstream::ClusterManager& cm,
             Event::Dispatcher& dispatcher, Runtime::RandomGenerator& random,
             Init::Manager& init_manager, const LocalInfo::LocalInfo& local_info,
             Stats::Scope& scope, ListenerManager& lm);

  // Server::LdsApi
  std::string versionInfo() const override { return version_info_; }

  // Init::Target
  void initialize(std::function<void()> callback) override;

  // Config::SubscriptionCallbacks
  void onConfigUpdate(const ResourceVector& resources, const std::string& version_info) override;
  void onConfigUpdateFailed(const EnvoyException* e) override;
  std::string resourceName(const ProtobufWkt::Any& resource) override {
    return MessageUtil::anyConvert<envoy::api::v2::Listener>(resource).name();
  }

private:
  void runInitializeCallbackIfAny();

  std::unique_ptr<Config::Subscription<envoy::api::v2::Listener>> subscription_;
  std::string version_info_;
  ListenerManager& listener_manager_;
  Stats::ScopePtr scope_;
  Upstream::ClusterManager& cm_;
  std::function<void()> initialize_callback_;
};

} // namespace Server
} // namespace Envoy


text:
<!DOCTYPE html>

	<meta charset="utf-8">
	<title>Java Guava – Maps</title>

	<meta name="description" content="Java Guava – Maps">

	<meta name="author" content="thswave">

	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta name="naver-site-verification" content="64ea16ae1fd0d7506cf163ca55131d4302a46961"/>

	<link href="/assets/resources/bootstrap/css/bootstrap.min.css" rel="stylesheet">
	<link href="/assets/resources/font-awesome/css/font-awesome.min.css" rel="stylesheet">
	<link href="/assets/resources/syntax/syntax.css" rel="stylesheet">
	<link href="/assets/css/style.css" rel="stylesheet">

	<link rel="alternate" type="application/rss+xml" title="thswave" href="/feed.xml">

			<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
				Toggle navigation

			</button>

				thswave

Home

Categories

Tags

		<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">

		</button>

Home

Categories

Tags

Top of Page

		<! -- sidebar.html -->

        thswave

	try hard, try hard!

Categories

Tags

<! -- sidebar.html end -->

Java Guava – Maps

	   March
	   14th,

	   2015

본 포스트의 원문은 http://www.baeldung.com에서 확인할 수 있으며 원 저작자의 번역 포스팅 허락을 받았음을 알려드립니다.

1. Overview

이번 튜토리얼에서 Guava를 통해 Java Map을 유용하게 사용할 수 있는 방법들에 대해 설명할 것입니다.

Guava를 통해 new 연산자 없이 HashMap 을 만드는 아주 간단한 방법을 살펴보도록 합시다.

Map<String, String> aNewMap = Maps.newHashMap();

2. ImmutableMap

다음으로 Guava를 통해 ImmutableMap 을 만드는 것을 살펴보겠습니다:

@Test
public void whenCreatingImmutableMap_thenCorrect() {
    Map<String, Integer> salary = ImmutableMap.<String, Integer> builder()
      .put("John", 1000)
      .put("Jane", 1500)
      .put("Adam", 2000)
      .put("Tom", 2000)
      .build();

    assertEquals(1000, salary.get("John").intValue());
    assertEquals(2000, salary.get("Tom").intValue());
}

3. SortedMap

이제 SortedMap을 만들고 사용하는 방법에 대해 살펴보겠습니다.

다음 예제는 - Guava builder 를 통해 sorted map을 만들겠습니다:

@Test
public void whenUsingSortedMap_thenKeysAreSorted() {
    ImmutableSortedMap<String, Integer> salary = new ImmutableSortedMap
      .Builder<String, Integer>(Ordering.natural())
      .put("John", 1000)
      .put("Jane", 1500)
      .put("Adam", 2000)
      .put("Tom", 2000)
      .build();

    assertEquals("Adam", salary.firstKey());
    assertEquals(2000, salary.lastEntry().getValue().intValue());
}

4. BiMap

다음으로 어떻게 BiMap을 사용하는지 살펴보겠습니다. BiMap은 map 의 value로 key 값을 찾을 수 있습니다.(value들이 유니크한 값을 가져야 합니다)

다음 예제는 - BiMap 을 만들고 inverse() 사용 예제를 살펴보겠습니다.

@Test
public void whenCreateBiMap_thenCreated() {
    BiMap<String, Integer> words = HashBiMap.create();
    words.put("First", 1);
    words.put("Second", 2);
    words.put("Third", 3);

    assertEquals(2, words.get("Second").intValue());
    assertEquals("Third", words.inverse().get(3));
}

5. Multimap

이제 Multimap을 살펴보겠습니다.

다음 예제에서 Multimap으로 각 key에 여러개의 value를 저장할 수 있음을 확인할 수 있습니다.

@Test
public void whenCreateMultimap_thenCreated() {
    Multimap<String, String> multimap = ArrayListMultimap.create();
    multimap.put("fruit", "apple");
    multimap.put("fruit", "banana");
    multimap.put("pet", "cat");
    multimap.put("pet", "dog");

    assertThat(multimap.get("fruit"), containsInAnyOrder("apple", "banana"));
    assertThat(multimap.get("pet"), containsInAnyOrder("cat", "dog"));
}

5. Table

이제는 Guava Table을 살펴볼 차례입니다; value에 하나 이상의 key가 필요할 때 Table을 사용합니다.
아래 예제는 두 도시간의 거리를 Table을 사용하여 저장하였습니다.

@Test
public void whenCreatingTable_thenCorrect() {
    Table<String,String,Integer> distance = HashBasedTable.create();
    distance.put("London", "Paris", 340);
    distance.put("New York", "Los Angeles", 3940);
    distance.put("London", "New York", 5576);

    assertEquals(3940, distance.get("New York", "Los Angeles").intValue());
    assertThat(distance.columnKeySet(),
      containsInAnyOrder("Paris", "New York", "Los Angeles"));
    assertThat(distance.rowKeySet(), containsInAnyOrder("London", "New York"));
}

그리고 아래 예제와 같이 Tables.transpose() 를 통해 row와 column 키를 뒤집을 수 있습니다.

@Test
public void whenTransposingTable_thenCorrect() {
    Table<String,String,Integer> distance = HashBasedTable.create();
    distance.put("London", "Paris", 340);
    distance.put("New York", "Los Angeles", 3940);
    distance.put("London", "New York", 5576);

    Table<String, String, Integer> transposed = Tables.transpose(distance);

    assertThat(transposed.rowKeySet(),
      containsInAnyOrder("Paris", "New York", "Los Angeles"));
    assertThat(transposed.columnKeySet(), containsInAnyOrder("London", "New York"));
}

6. ClassToInstanceMap

다음으로 ClassToInstanseMap을 살펴보겠습니다. object의 클래스를 key로 사용하고자 할 경우 ClassToInstanceMap을 사용할 수 있습니다.

@Test
public void whenCreatingClassToInstanceMap_thenCorrect() {
    ClassToInstanceMap<Number> numbers = MutableClassToInstanceMap.create();
    numbers.putInstance(Integer.class, 1);
    numbers.putInstance(Double.class, 1.5);

    assertEquals(1, numbers.get(Integer.class));
    assertEquals(1.5, numbers.get(Double.class));
}

7. Group List using Multimap

다음은 Multimap을 통해 List를 그룹화 하는것을 보겠습니다. 다음 예제에서 Multimaps.index() 를 사용해 리스트에 있는 이름(names)의 길이로 그룹화 시킬 수 있습니다.

@Test
public void whenGroupingListsUsingMultimap_thenGrouped() {
    List<String> names = Lists.newArrayList("John", "Adam", "Tom");
    Function<String,Integer> func = new Function<String,Integer>(){
        public Integer apply(String input) {
            return input.length();
        }
    };
    Multimap<Integer, String> groups = Multimaps.index(names, func);

    assertThat(groups.get(3), containsInAnyOrder("Tom"));
    assertThat(groups.get(4), containsInAnyOrder("John", "Adam"));
}

8. Conclusion

위 예제들을 통해 Guava 라이브러리를 통해 Map을 유용하게 사용할 수 있는 여러가지 예제를 살펴봤습니다.
위 예제 코드들은 Guava github 프로젝트에서 찾아볼 수 있습니다. - 이클립스 기반 프로젝트로 쉽게 import하여 사용할 수 있습니다.

					java (17)

					java (18)
					,

					guava (4)

Share Post

          Twitter

          Facebook

          Google+

thswave

try hard, try hard!

← Previous

Next →

    Please enable JavaScript to view the comments powered by Disqus.

	    Please enable JavaScript to view the comments powered by Disqus.

				© 2016 thswave with Jekyll. Theme: dbyll by dbtek.


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
                "http://www.w3.org/TR/REC-html40/loose.dtd">

  <title>Index for Directory qcat</title>
  <meta name="keywords" content="qcat">
  <meta name="description" content="Index for Directory qcat">
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  <meta name="generator" content="m2html © 2003 Guillaume Flandin">
  <meta name="robots" content="index, follow">
  <link type="text/css" rel="stylesheet" href="menu.css">

QCAT

About

Introduction

What's new

Functions &nbsp

Help

help qcat

qcatdoc

QP allocation

sls_alloc

wls_alloc
      [in C]

mls_alloc

ip_alloc

cgi_alloc

fxp_alloc

Direct allocation

dir_alloc

Dynamic allocation

dca

Simulation

qp_sim

dir_sim

dyn_sim

qcatlib

Linear control

lq2ca

ca2lq

vview

vview_demo

Other

iscoplanar

wpinv

Data files &nbsp

Aircraft data

admiredata.mat

f18data.mat

<address>Generated by m2html © 2003</address>


text:
"""rope, a python refactoring library"""

INFO = __doc__
VERSION = '0.20.1'
COPYRIGHT = """\
Copyright (C) 2019-2021 Matej Cepl
Copyright (C) 2015-2018 Nicholas Smith
Copyright (C) 2014-2015 Matej Cepl
Copyright (C) 2006-2012 Ali Gholami Rudi
Copyright (C) 2009-2012 Anton Gritsay

This program is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation, either
version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this program.  If not, see
<https://www.gnu.org/licenses/>."""


text:
import numpy as np;
from numpy.linalg import inv
from numpy.linalg import svd
from numpy.linalg import eig
from numpy.linalg import det
from scipy.optimize import leastsq,least_squares,fmin
import pandas as pd
import numpy as np
import time
import random
from stl import mesh
from scipy.spatial import Delaunay

class RecModel:
	'''
	Class to hold all the result of a reconstruction
	'''
	def __init__(self):
		self._P = 0			#projection matrices for each view
		self._R = 0			#rotation matrices for each view
		self._t = 0			#translation vectors for each view
		self._points3D=0	#3D points in metric space
		self._Tm=0			#Transformation matrix from projective to metric

	@property
	def P(self):
		return self._P

	@P.setter
	def P(self,val):
		self._R,self._t=extract_rotation_translation(P)
		self._P=val

	@property
	def points3D(self):
		return self._points3D

	@points3D.setter
	def points3D(self,val):
		self._points3D=val

	def extract_rotation_translation(self, P):
		'''
		Method to extract the rotation matrices and translation vectors from the projection matrices
		'''
		sequence_length=P.shape[2]
		R=np.zeros((3,3,self._sequence_length))
		t=np.zeros((3,self._sequence_length))

		for i in range(1,self._sequence_length):
			PP=inv(K[:,:,i]).dot(P[:,:,i]);
			R[:,:,i]=np.transpose(PP[0:3,0:3])
			t[:,i]=-inv(np.transpose(R[:,:,i])).dot(PP[0:3,3])
		return R,t

	def export_stl_file(self,filename):
		'''
		Method that generates an .stl file with the generated model
		'''
		vertices=self.points3D[:,0:3];

		faces=Delaunay(vertices[:,0:2],incremental=1);
		faces= faces.simplices;

		wireframe = mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype))
		for i, f in enumerate(faces):
		    for j in range(3):
		        wireframe.vectors[i][j] = vertices[f[j],:]

		wireframe.save(filename)


text:
title: "Attendee"
event: "CodeConf"
---

GitHub [CodeConf](http://codeconf.com/) 2016


text:
package com.amazonaws.services.timestreamquery.model;

import java.io.Serializable;
import javax.annotation.Generated;

/**
 *
 * @see AWS API Documentation
 */
@Generated("com.amazonaws:aws-java-sdk-code-generator")
public class CreateScheduledQueryResult extends com.amazonaws.AmazonWebServiceResult<com.amazonaws.ResponseMetadata> implements Serializable, Cloneable {

    /**
     *

     * ARN for the created scheduled query.
     *

     */
    private String arn;

    /**
     *

     * ARN for the created scheduled query.
     *

     *
     * @param arn
     *        ARN for the created scheduled query.
     */

    public void setArn(String arn) {
        this.arn = arn;
    }

    /**
     *

     * ARN for the created scheduled query.
     *

     *
     * @return ARN for the created scheduled query.
     */

    public String getArn() {
        return this.arn;
    }

    /**
     *

     * ARN for the created scheduled query.
     *

     *
     * @param arn
     *        ARN for the created scheduled query.
     * @return Returns a reference to this object so that method calls can be chained together.
     */

    public CreateScheduledQueryResult withArn(String arn) {
        setArn(arn);
        return this;
    }

    /**
     * Returns a string representation of this object. This is useful for testing and debugging. Sensitive data will be
     * redacted from this string using a placeholder value.
     *
     * @return A string representation of this object.
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("{");
        if (getArn() != null)
            sb.append("Arn: ").append(getArn());
        sb.append("}");
        return sb.toString();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;

        if (obj instanceof CreateScheduledQueryResult == false)
            return false;
        CreateScheduledQueryResult other = (CreateScheduledQueryResult) obj;
        if (other.getArn() == null ^ this.getArn() == null)
            return false;
        if (other.getArn() != null && other.getArn().equals(this.getArn()) == false)
            return false;
        return true;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int hashCode = 1;

        hashCode = prime * hashCode + ((getArn() == null) ? 0 : getArn().hashCode());
        return hashCode;
    }

    @Override
    public CreateScheduledQueryResult clone() {
        try {
            return (CreateScheduledQueryResult) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new IllegalStateException("Got a CloneNotSupportedException from Object.clone() " + "even though we're Cloneable!", e);
        }
    }

}


text:
using System;
using System.Diagnostics;
using System.Reflection;
using System.Windows.Media;
using System.Windows.Media.Imaging;

using ICSharpCode.AvalonEdit.CodeCompletion;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Editing;

using Roslyn.Compilers;
using Roslyn.Services;

namespace ScriptCsPad.Completion
{
    public class CompletionData : ICompletionData
    {
        private readonly CompletionItem _completionItem;

        private string _description;

        public CompletionData(CompletionItem completionItem)
        {
            _completionItem = completionItem;
        }

        public ImageSource Image
        {
            get
            {
                if (!_completionItem.Glyph.HasValue) return null;

                var fileName = string.Format("{0}.png", _completionItem.Glyph).ToLowerInvariant();
                var resourceName = string.Format("ScriptCsPad.Resources.{0}", fileName);

                var assembly = Assembly.GetExecutingAssembly();
                using (var stream = assembly.GetManifestResourceStream(resourceName))
                {
                    if (stream == null)
                    {
                        Debug.Print(resourceName);
                        return null;
                    }

                    var bitmapImage = new BitmapImage();

                    bitmapImage.BeginInit();
                    bitmapImage.StreamSource = stream;
                    bitmapImage.DecodePixelHeight = 16;
                    bitmapImage.EndInit();

                    return bitmapImage;
                }
            }
        }

        public string Text
        {
            get { return _completionItem.DisplayText; }
        }

        public object Content
        {
            get { return _completionItem.DisplayText; }
        }

        public object Description
        {
            get { return _description ?? (_description = _completionItem.GetDescription().ToDisplayString()); }
        }

        public double Priority { get { return 0; } }

        public void Complete(TextArea textArea, ISegment completionSegment, EventArgs insertionRequestEventArgs)
        {
            var offset = completionSegment.Offset - 1;
            var length = completionSegment.Length + 1;

            textArea.Document.Replace(offset, length, Text);
        }
    }
}


text:
@ApiStatus.Internal
package com.intellij.codeInsight.signatureHelp;

import org.jetbrains.annotations.ApiStatus;


text:
.class Lcom/android/internal/policy/impl/keyguard/KeyguardSimPinView$1;
.super Ljava/lang/Object;
.source "KeyguardSimPinView.java"

# interfaces
.implements Landroid/view/View$OnClickListener;

# annotations
.annotation system Ldalvik/annotation/EnclosingMethod;
    value = Lcom/android/internal/policy/impl/keyguard/KeyguardSimPinView;->onFinishInflate()V
.end annotation

.annotation system Ldalvik/annotation/InnerClass;
    accessFlags = 0x0
    name = null
.end annotation

# instance fields
.field final synthetic this$0:Lcom/android/internal/policy/impl/keyguard/KeyguardSimPinView;

# direct methods
.method constructor <init>(Lcom/android/internal/policy/impl/keyguard/KeyguardSimPinView;)V
    .locals 0
    .parameter

    .prologue
    .line 71
    iput-object p1, p0, Lcom/android/internal/policy/impl/keyguard/KeyguardSimPinView$1;->this$0:Lcom/android/internal/policy/impl/keyguard/KeyguardSimPinView;

    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method

# virtual methods
.method public onClick(Landroid/view/View;)V
    .locals 1
    .parameter "v"

    .prologue
    .line 74
    iget-object v0, p0, Lcom/android/internal/policy/impl/keyguard/KeyguardSimPinView$1;->this$0:Lcom/android/internal/policy/impl/keyguard/KeyguardSimPinView;

    invoke-virtual {v0}, Lcom/android/internal/policy/impl/keyguard/KeyguardSimPinView;->doHapticKeyClick()V

    .line 75
    iget-object v0, p0, Lcom/android/internal/policy/impl/keyguard/KeyguardSimPinView$1;->this$0:Lcom/android/internal/policy/impl/keyguard/KeyguardSimPinView;

    invoke-virtual {v0}, Lcom/android/internal/policy/impl/keyguard/KeyguardSimPinView;->verifyPasswordAndUnlock()V

    .line 76
    return-void
.end method


text:
package validation

import (
	"strings"
	"testing"

	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	utilfeature "k8s.io/apiserver/pkg/util/feature"
	featuregatetesting "k8s.io/component-base/featuregate/testing"
	"k8s.io/kubernetes/pkg/apis/autoscaling"
	api "k8s.io/kubernetes/pkg/apis/core"
	"k8s.io/kubernetes/pkg/features"
	utilpointer "k8s.io/utils/pointer"
)

func TestValidateScale(t *testing.T) {
	successCases := []autoscaling.Scale{
		{
			ObjectMeta: metav1.ObjectMeta{
				Name:      "frontend",
				Namespace: metav1.NamespaceDefault,
			},
			Spec: autoscaling.ScaleSpec{
				Replicas: 1,
			},
		},
		{
			ObjectMeta: metav1.ObjectMeta{
				Name:      "frontend",
				Namespace: metav1.NamespaceDefault,
			},
			Spec: autoscaling.ScaleSpec{
				Replicas: 10,
			},
		},
		{
			ObjectMeta: metav1.ObjectMeta{
				Name:      "frontend",
				Namespace: metav1.NamespaceDefault,
			},
			Spec: autoscaling.ScaleSpec{
				Replicas: 0,
			},
		},
	}

	for _, successCase := range successCases {
		if errs := ValidateScale(&successCase); len(errs) != 0 {
			t.Errorf("expected success: %v", errs)
		}
	}

	errorCases := []struct {
		scale autoscaling.Scale
		msg   string
	}{
		{
			scale: autoscaling.Scale{
				ObjectMeta: metav1.ObjectMeta{
					Name:      "frontend",
					Namespace: metav1.NamespaceDefault,
				},
				Spec: autoscaling.ScaleSpec{
					Replicas: -1,
				},
			},
			msg: "must be greater than or equal to 0",
		},
	}

	for _, c := range errorCases {
		if errs := ValidateScale(&c.scale); len(errs) == 0 {
			t.Errorf("expected failure for %s", c.msg)
		} else if !strings.Contains(errs[0].Error(), c.msg) {
			t.Errorf("unexpected error: %v, expected: %s", errs[0], c.msg)
		}
	}
}

func TestValidateBehavior(t *testing.T) {
	maxPolicy := autoscaling.MaxPolicySelect
	minPolicy := autoscaling.MinPolicySelect
	disabledPolicy := autoscaling.DisabledPolicySelect
	incorrectPolicy := autoscaling.ScalingPolicySelect("incorrect")
	simplePoliciesList := []autoscaling.HPAScalingPolicy{
		{
			Type:          autoscaling.PercentScalingPolicy,
			Value:         10,
			PeriodSeconds: 1,
		},
		{
			Type:          autoscaling.PodsScalingPolicy,
			Value:         1,
			PeriodSeconds: 1800,
		},
	}
	successCases := []autoscaling.HorizontalPodAutoscalerBehavior{
		{
			ScaleUp:   nil,
			ScaleDown: nil,
		},
		{
			ScaleUp: &autoscaling.HPAScalingRules{
				StabilizationWindowSeconds: utilpointer.Int32Ptr(3600),
				SelectPolicy:               &minPolicy,
				Policies:                   simplePoliciesList,
			},
			ScaleDown: &autoscaling.HPAScalingRules{
				StabilizationWindowSeconds: utilpointer.Int32Ptr(0),
				SelectPolicy:               &disabledPolicy,
				Policies:                   simplePoliciesList,
			},
		},
		{
			ScaleUp: &autoscaling.HPAScalingRules{
				StabilizationWindowSeconds: utilpointer.Int32Ptr(120),
				SelectPolicy:               &maxPolicy,
				Policies: []autoscaling.HPAScalingPolicy{
					{
						Type:          autoscaling.PodsScalingPolicy,
						Value:         1,
						PeriodSeconds: 2,
					},
					{
						Type:          autoscaling.PercentScalingPolicy,
						Value:         3,
						PeriodSeconds: 4,
					},
					{
						Type:          autoscaling.PodsScalingPolicy,
						Value:         5,
						PeriodSeconds: 6,
					},
					{
						Type:          autoscaling.PercentScalingPolicy,
						Value:         7,
						PeriodSeconds: 8,
					},
				},
			},
			ScaleDown: &autoscaling.HPAScalingRules{
				StabilizationWindowSeconds: utilpointer.Int32Ptr(120),
				SelectPolicy:               &maxPolicy,
				Policies: []autoscaling.HPAScalingPolicy{
					{
						Type:          autoscaling.PodsScalingPolicy,
						Value:         1,
						PeriodSeconds: 2,
					},
					{
						Type:          autoscaling.PercentScalingPolicy,
						Value:         3,
						PeriodSeconds: 4,
					},
					{
						Type:          autoscaling.PodsScalingPolicy,
						Value:         5,
						PeriodSeconds: 6,
					},
					{
						Type:          autoscaling.PercentScalingPolicy,
						Value:         7,
						PeriodSeconds: 8,
					},
				},
			},
		},
	}
	for _, behavior := range successCases {
		hpa := prepareHPAWithBehavior(behavior)
		if errs := ValidateHorizontalPodAutoscaler(&hpa); len(errs) != 0 {
			t.Errorf("expected success: %v", errs)
		}
	}
	errorCases := []struct {
		behavior autoscaling.HorizontalPodAutoscalerBehavior
		msg      string
	}{
		{
			behavior: autoscaling.HorizontalPodAutoscalerBehavior{
				ScaleUp: &autoscaling.HPAScalingRules{
					SelectPolicy: &minPolicy,
				},
			},
			msg: "spec.behavior.scaleUp.policies: Required value: must specify at least one Policy",
		},
		{
			behavior: autoscaling.HorizontalPodAutoscalerBehavior{
				ScaleUp: &autoscaling.HPAScalingRules{
					StabilizationWindowSeconds: utilpointer.Int32Ptr(3601),
					SelectPolicy:               &minPolicy,
					Policies:                   simplePoliciesList,
				},
			},
			msg: "spec.behavior.scaleUp.stabilizationWindowSeconds: Invalid value: 3601: must be less than or equal to 3600",
		},
		{
			behavior: autoscaling.HorizontalPodAutoscalerBehavior{
				ScaleUp: &autoscaling.HPAScalingRules{
					Policies: []autoscaling.HPAScalingPolicy{
						{
							Type:          autoscaling.PodsScalingPolicy,
							Value:         7,
							PeriodSeconds: 1801,
						},
					},
				},
			},
			msg: "spec.behavior.scaleUp.policies[0].periodSeconds: Invalid value: 1801: must be less than or equal to 1800",
		},
		{
			behavior: autoscaling.HorizontalPodAutoscalerBehavior{
				ScaleUp: &autoscaling.HPAScalingRules{
					SelectPolicy: &incorrectPolicy,
					Policies: []autoscaling.HPAScalingPolicy{
						{
							Type:          autoscaling.PodsScalingPolicy,
							Value:         7,
							PeriodSeconds: 8,
						},
					},
				},
			},
			msg: `spec.behavior.scaleUp.selectPolicy: Unsupported value: "incorrect": supported values: "Disabled", "Max", "Min"`,
		},
		{
			behavior: autoscaling.HorizontalPodAutoscalerBehavior{
				ScaleUp: &autoscaling.HPAScalingRules{
					Policies: []autoscaling.HPAScalingPolicy{
						{
							Type:          autoscaling.HPAScalingPolicyType("hm"),
							Value:         7,
							PeriodSeconds: 8,
						},
					},
				},
			},
			msg: `spec.behavior.scaleUp.policies[0].type: Unsupported value: "hm": supported values: "Percent", "Pods"`,
		},
		{
			behavior: autoscaling.HorizontalPodAutoscalerBehavior{
				ScaleUp: &autoscaling.HPAScalingRules{
					Policies: []autoscaling.HPAScalingPolicy{
						{
							Type:  autoscaling.PodsScalingPolicy,
							Value: 8,
						},
					},
				},
			},
			msg: "spec.behavior.scaleUp.policies[0].periodSeconds: Invalid value: 0: must be greater than zero",
		},
		{
			behavior: autoscaling.HorizontalPodAutoscalerBehavior{
				ScaleUp: &autoscaling.HPAScalingRules{
					Policies: []autoscaling.HPAScalingPolicy{
						{
							Type:          autoscaling.PodsScalingPolicy,
							PeriodSeconds: 8,
						},
					},
				},
			},
			msg: "spec.behavior.scaleUp.policies[0].value: Invalid value: 0: must be greater than zero",
		},
		{
			behavior: autoscaling.HorizontalPodAutoscalerBehavior{
				ScaleUp: &autoscaling.HPAScalingRules{
					Policies: []autoscaling.HPAScalingPolicy{
						{
							Type:          autoscaling.PodsScalingPolicy,
							PeriodSeconds: -1,
							Value:         1,
						},
					},
				},
			},
			msg: "spec.behavior.scaleUp.policies[0].periodSeconds: Invalid value: -1: must be greater than zero",
		},
		{
			behavior: autoscaling.HorizontalPodAutoscalerBehavior{
				ScaleUp: &autoscaling.HPAScalingRules{
					Policies: []autoscaling.HPAScalingPolicy{
						{
							Type:          autoscaling.PodsScalingPolicy,
							PeriodSeconds: 1,
							Value:         -1,
						},
					},
				},
			},
			msg: "spec.behavior.scaleUp.policies[0].value: Invalid value: -1: must be greater than zero",
		},
		{
			behavior: autoscaling.HorizontalPodAutoscalerBehavior{
				ScaleDown: &autoscaling.HPAScalingRules{
					SelectPolicy: &minPolicy,
				},
			},
			msg: "spec.behavior.scaleDown.policies: Required value: must specify at least one Policy",
		},
		{
			behavior: autoscaling.HorizontalPodAutoscalerBehavior{
				ScaleDown: &autoscaling.HPAScalingRules{
					StabilizationWindowSeconds: utilpointer.Int32Ptr(3601),
					SelectPolicy:               &minPolicy,
					Policies:                   simplePoliciesList,
				},
			},
			msg: "spec.behavior.scaleDown.stabilizationWindowSeconds: Invalid value: 3601: must be less than or equal to 3600",
		},
		{
			behavior: autoscaling.HorizontalPodAutoscalerBehavior{
				ScaleDown: &autoscaling.HPAScalingRules{
					Policies: []autoscaling.HPAScalingPolicy{
						{
							Type:          autoscaling.PercentScalingPolicy,
							Value:         7,
							PeriodSeconds: 1801,
						},
					},
				},
			},
			msg: "spec.behavior.scaleDown.policies[0].periodSeconds: Invalid value: 1801: must be less than or equal to 1800",
		},
		{
			behavior: autoscaling.HorizontalPodAutoscalerBehavior{
				ScaleDown: &autoscaling.HPAScalingRules{
					SelectPolicy: &incorrectPolicy,
					Policies: []autoscaling.HPAScalingPolicy{
						{
							Type:          autoscaling.PodsScalingPolicy,
							Value:         7,
							PeriodSeconds: 8,
						},
					},
				},
			},
			msg: `spec.behavior.scaleDown.selectPolicy: Unsupported value: "incorrect": supported values: "Disabled", "Max", "Min"`,
		},
		{
			behavior: autoscaling.HorizontalPodAutoscalerBehavior{
				ScaleDown: &autoscaling.HPAScalingRules{
					Policies: []autoscaling.HPAScalingPolicy{
						{
							Type:          autoscaling.HPAScalingPolicyType("hm"),
							Value:         7,
							PeriodSeconds: 8,
						},
					},
				},
			},
			msg: `spec.behavior.scaleDown.policies[0].type: Unsupported value: "hm": supported values: "Percent", "Pods"`,
		},
		{
			behavior: autoscaling.HorizontalPodAutoscalerBehavior{
				ScaleDown: &autoscaling.HPAScalingRules{
					Policies: []autoscaling.HPAScalingPolicy{
						{
							Type:  autoscaling.PodsScalingPolicy,
							Value: 8,
						},
					},
				},
			},
			msg: "spec.behavior.scaleDown.policies[0].periodSeconds: Invalid value: 0: must be greater than zero",
		},
		{
			behavior: autoscaling.HorizontalPodAutoscalerBehavior{
				ScaleDown: &autoscaling.HPAScalingRules{
					Policies: []autoscaling.HPAScalingPolicy{
						{
							Type:          autoscaling.PodsScalingPolicy,
							PeriodSeconds: 8,
						},
					},
				},
			},
			msg: "spec.behavior.scaleDown.policies[0].value: Invalid value: 0: must be greater than zero",
		},
		{
			behavior: autoscaling.HorizontalPodAutoscalerBehavior{
				ScaleDown: &autoscaling.HPAScalingRules{
					Policies: []autoscaling.HPAScalingPolicy{
						{
							Type:          autoscaling.PodsScalingPolicy,
							PeriodSeconds: -1,
							Value:         1,
						},
					},
				},
			},
			msg: "spec.behavior.scaleDown.policies[0].periodSeconds: Invalid value: -1: must be greater than zero",
		},
		{
			behavior: autoscaling.HorizontalPodAutoscalerBehavior{
				ScaleDown: &autoscaling.HPAScalingRules{
					Policies: []autoscaling.HPAScalingPolicy{
						{
							Type:          autoscaling.PodsScalingPolicy,
							PeriodSeconds: 1,
							Value:         -1,
						},
					},
				},
			},
			msg: "spec.behavior.scaleDown.policies[0].value: Invalid value: -1: must be greater than zero",
		},
	}
	for _, c := range errorCases {
		hpa := prepareHPAWithBehavior(c.behavior)
		if errs := ValidateHorizontalPodAutoscaler(&hpa); len(errs) == 0 {
			t.Errorf("expected failure for %s", c.msg)
		} else if !strings.Contains(errs[0].Error(), c.msg) {
			t.Errorf("unexpected error: %v, expected: %s", errs[0], c.msg)
		}
	}
}

func prepareHPAWithBehavior(b autoscaling.HorizontalPodAutoscalerBehavior) autoscaling.HorizontalPodAutoscaler {
	return autoscaling.HorizontalPodAutoscaler{
		ObjectMeta: metav1.ObjectMeta{
			Name:      "myautoscaler",
			Namespace: metav1.NamespaceDefault,
		},
		Spec: autoscaling.HorizontalPodAutoscalerSpec{
			ScaleTargetRef: autoscaling.CrossVersionObjectReference{
				Kind: "ReplicationController",
				Name: "myrc",
			},
			MinReplicas: utilpointer.Int32Ptr(1),
			MaxReplicas: 5,
			Metrics: []autoscaling.MetricSpec{
				{
					Type: autoscaling.ResourceMetricSourceType,
					Resource: &autoscaling.ResourceMetricSource{
						Name: api.ResourceCPU,
						Target: autoscaling.MetricTarget{
							Type:               autoscaling.UtilizationMetricType,
							AverageUtilization: utilpointer.Int32Ptr(70),
						},
					},
				},
			},
			Behavior: &b,
		},
	}
}

func TestValidateHorizontalPodAutoscaler(t *testing.T) {
	metricLabelSelector, err := metav1.ParseToLabelSelector("label=value")
	if err != nil {
		t.Errorf("unable to parse label selector: %v", err)
	}

	successCases := []autoscaling.HorizontalPodAutoscaler{
		{
			ObjectMeta: metav1.ObjectMeta{
				Name:      "myautoscaler",
				Namespace: metav1.NamespaceDefault,
			},
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{
					Kind: "ReplicationController",
					Name: "myrc",
				},
				MinReplicas: utilpointer.Int32Ptr(1),
				MaxReplicas: 5,
				Metrics: []autoscaling.MetricSpec{
					{
						Type: autoscaling.ResourceMetricSourceType,
						Resource: &autoscaling.ResourceMetricSource{
							Name: api.ResourceCPU,
							Target: autoscaling.MetricTarget{
								Type:               autoscaling.UtilizationMetricType,
								AverageUtilization: utilpointer.Int32Ptr(70),
							},
						},
					},
				},
			},
		},
		{
			ObjectMeta: metav1.ObjectMeta{
				Name:      "myautoscaler",
				Namespace: metav1.NamespaceDefault,
			},
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{
					Kind: "ReplicationController",
					Name: "myrc",
				},
				MinReplicas: utilpointer.Int32Ptr(1),
				MaxReplicas: 5,
			},
		},
		{
			ObjectMeta: metav1.ObjectMeta{
				Name:      "myautoscaler",
				Namespace: metav1.NamespaceDefault,
			},
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{
					Kind: "ReplicationController",
					Name: "myrc",
				},
				MinReplicas: utilpointer.Int32Ptr(1),
				MaxReplicas: 5,
				Metrics: []autoscaling.MetricSpec{
					{
						Type: autoscaling.ResourceMetricSourceType,
						Resource: &autoscaling.ResourceMetricSource{
							Name: api.ResourceCPU,
							Target: autoscaling.MetricTarget{
								Type:         autoscaling.AverageValueMetricType,
								AverageValue: resource.NewMilliQuantity(300, resource.DecimalSI),
							},
						},
					},
				},
			},
		},
		{
			ObjectMeta: metav1.ObjectMeta{
				Name:      "myautoscaler",
				Namespace: metav1.NamespaceDefault,
			},
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{
					Kind: "ReplicationController",
					Name: "myrc",
				},
				MinReplicas: utilpointer.Int32Ptr(1),
				MaxReplicas: 5,
				Metrics: []autoscaling.MetricSpec{
					{
						Type: autoscaling.PodsMetricSourceType,
						Pods: &autoscaling.PodsMetricSource{
							Metric: autoscaling.MetricIdentifier{
								Name: "somemetric",
							},
							Target: autoscaling.MetricTarget{
								Type:         autoscaling.AverageValueMetricType,
								AverageValue: resource.NewMilliQuantity(300, resource.DecimalSI),
							},
						},
					},
				},
			},
		},
		{
			ObjectMeta: metav1.ObjectMeta{
				Name:      "myautoscaler",
				Namespace: metav1.NamespaceDefault,
			},
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{
					Kind: "ReplicationController",
					Name: "myrc",
				},
				MinReplicas: utilpointer.Int32Ptr(1),
				MaxReplicas: 5,
				Metrics: []autoscaling.MetricSpec{
					{
						Type: autoscaling.ObjectMetricSourceType,
						Object: &autoscaling.ObjectMetricSource{
							DescribedObject: autoscaling.CrossVersionObjectReference{
								Kind: "ReplicationController",
								Name: "myrc",
							},
							Metric: autoscaling.MetricIdentifier{
								Name: "somemetric",
							},
							Target: autoscaling.MetricTarget{
								Type:  autoscaling.ValueMetricType,
								Value: resource.NewMilliQuantity(300, resource.DecimalSI),
							},
						},
					},
				},
			},
		},
		{
			ObjectMeta: metav1.ObjectMeta{
				Name:      "myautoscaler",
				Namespace: metav1.NamespaceDefault,
			},
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{
					Kind: "ReplicationController",
					Name: "myrc",
				},
				MinReplicas: utilpointer.Int32Ptr(1),
				MaxReplicas: 5,
				Metrics: []autoscaling.MetricSpec{
					{
						Type: autoscaling.ExternalMetricSourceType,
						External: &autoscaling.ExternalMetricSource{
							Metric: autoscaling.MetricIdentifier{
								Name:     "somemetric",
								Selector: metricLabelSelector,
							},
							Target: autoscaling.MetricTarget{
								Type:  autoscaling.ValueMetricType,
								Value: resource.NewMilliQuantity(300, resource.DecimalSI),
							},
						},
					},
				},
			},
		},
		{
			ObjectMeta: metav1.ObjectMeta{
				Name:      "myautoscaler",
				Namespace: metav1.NamespaceDefault,
			},
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{
					Kind: "ReplicationController",
					Name: "myrc",
				},
				MinReplicas: utilpointer.Int32Ptr(1),
				MaxReplicas: 5,
				Metrics: []autoscaling.MetricSpec{
					{
						Type: autoscaling.ExternalMetricSourceType,
						External: &autoscaling.ExternalMetricSource{
							Metric: autoscaling.MetricIdentifier{
								Name:     "somemetric",
								Selector: metricLabelSelector,
							},
							Target: autoscaling.MetricTarget{
								Type:         autoscaling.AverageValueMetricType,
								AverageValue: resource.NewMilliQuantity(300, resource.DecimalSI),
							},
						},
					},
				},
			},
		},
	}
	for _, successCase := range successCases {
		if errs := ValidateHorizontalPodAutoscaler(&successCase); len(errs) != 0 {
			t.Errorf("expected success: %v", errs)
		}
	}

	errorCases := []struct {
		horizontalPodAutoscaler autoscaling.HorizontalPodAutoscaler
		msg                     string
	}{
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ResourceMetricSourceType,
							Resource: &autoscaling.ResourceMetricSource{
								Name: api.ResourceCPU,
								Target: autoscaling.MetricTarget{
									Type:               autoscaling.UtilizationMetricType,
									AverageUtilization: utilpointer.Int32Ptr(70),
								},
							},
						},
					},
				},
			},
			msg: "scaleTargetRef.kind: Required",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Kind: "..", Name: "myrc"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ResourceMetricSourceType,
							Resource: &autoscaling.ResourceMetricSource{
								Name: api.ResourceCPU,
								Target: autoscaling.MetricTarget{
									Type:               autoscaling.UtilizationMetricType,
									AverageUtilization: utilpointer.Int32Ptr(70),
								},
							},
						},
					},
				},
			},
			msg: "scaleTargetRef.kind: Invalid",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ResourceMetricSourceType,
							Resource: &autoscaling.ResourceMetricSource{
								Name: api.ResourceCPU,
								Target: autoscaling.MetricTarget{
									Type:               autoscaling.UtilizationMetricType,
									AverageUtilization: utilpointer.Int32Ptr(70),
								},
							},
						},
					},
				},
			},
			msg: "scaleTargetRef.name: Required",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Kind: "ReplicationController", Name: ".."},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ResourceMetricSourceType,
							Resource: &autoscaling.ResourceMetricSource{
								Name: api.ResourceCPU,
								Target: autoscaling.MetricTarget{
									Type:               autoscaling.UtilizationMetricType,
									AverageUtilization: utilpointer.Int32Ptr(70),
								},
							},
						},
					},
				},
			},
			msg: "scaleTargetRef.name: Invalid",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{
					Name:      "myautoscaler",
					Namespace: metav1.NamespaceDefault,
				},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{},
					MinReplicas:    utilpointer.Int32Ptr(-1),
					MaxReplicas:    5,
				},
			},
			msg: "must be greater than or equal to 1",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{
					Name:      "myautoscaler",
					Namespace: metav1.NamespaceDefault,
				},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{},
					MinReplicas:    utilpointer.Int32Ptr(7),
					MaxReplicas:    5,
				},
			},
			msg: "must be greater than or equal to `minReplicas`",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{
					Name:      "myautoscaler",
					Namespace: metav1.NamespaceDefault,
				},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ResourceMetricSourceType,
							Resource: &autoscaling.ResourceMetricSource{
								Name: api.ResourceCPU,
								Target: autoscaling.MetricTarget{
									Type:               autoscaling.UtilizationMetricType,
									AverageUtilization: utilpointer.Int32Ptr(70),
									AverageValue:       resource.NewMilliQuantity(300, resource.DecimalSI),
								},
							},
						},
					},
				},
			},
			msg: "may not set both a target raw value and a target utilization",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ResourceMetricSourceType,
							Resource: &autoscaling.ResourceMetricSource{
								Target: autoscaling.MetricTarget{
									Type:               autoscaling.UtilizationMetricType,
									AverageUtilization: utilpointer.Int32Ptr(70),
								},
							},
						},
					},
				},
			},
			msg: "must specify a resource name",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ResourceMetricSourceType,
							Resource: &autoscaling.ResourceMetricSource{
								Name: api.ResourceCPU,
								Target: autoscaling.MetricTarget{
									Type:               autoscaling.UtilizationMetricType,
									AverageUtilization: utilpointer.Int32Ptr(-10),
								},
							},
						},
					},
				},
			},
			msg: "must be greater than 0",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ResourceMetricSourceType,
							Resource: &autoscaling.ResourceMetricSource{
								Name: api.ResourceCPU,
								Target: autoscaling.MetricTarget{
									Type: autoscaling.ValueMetricType,
								},
							},
						},
					},
				},
			},
			msg: "must set either a target raw value or a target utilization",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.PodsMetricSourceType,
							Pods: &autoscaling.PodsMetricSource{
								Metric: autoscaling.MetricIdentifier{},
								Target: autoscaling.MetricTarget{
									Type:         autoscaling.ValueMetricType,
									AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
								},
							},
						},
					},
				},
			},
			msg: "must specify a metric name",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.PodsMetricSourceType,
							Pods: &autoscaling.PodsMetricSource{
								Metric: autoscaling.MetricIdentifier{
									Name: "somemetric",
								},
								Target: autoscaling.MetricTarget{
									Type: autoscaling.ValueMetricType,
								},
							},
						},
					},
				},
			},
			msg: "must specify a positive target averageValue",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ObjectMetricSourceType,
							Object: &autoscaling.ObjectMetricSource{
								DescribedObject: autoscaling.CrossVersionObjectReference{
									Kind: "ReplicationController",
									Name: "myrc",
								},
								Metric: autoscaling.MetricIdentifier{
									Name: "somemetric",
								},
								Target: autoscaling.MetricTarget{
									Type: autoscaling.ValueMetricType,
								},
							},
						},
					},
				},
			},
			msg: "must set either a target value or averageValue",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ObjectMetricSourceType,
							Object: &autoscaling.ObjectMetricSource{
								DescribedObject: autoscaling.CrossVersionObjectReference{
									Name: "myrc",
								},
								Metric: autoscaling.MetricIdentifier{
									Name: "somemetric",
								},
								Target: autoscaling.MetricTarget{
									Type:  autoscaling.ValueMetricType,
									Value: resource.NewMilliQuantity(100, resource.DecimalSI),
								},
							},
						},
					},
				},
			},
			msg: "object.describedObject.kind: Required",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ObjectMetricSourceType,
							Object: &autoscaling.ObjectMetricSource{
								DescribedObject: autoscaling.CrossVersionObjectReference{
									Kind: "ReplicationController",
									Name: "myrc",
								},
								Target: autoscaling.MetricTarget{
									Type:  autoscaling.ValueMetricType,
									Value: resource.NewMilliQuantity(100, resource.DecimalSI),
								},
							},
						},
					},
				},
			},
			msg: "must specify a metric name",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ExternalMetricSourceType,
							External: &autoscaling.ExternalMetricSource{
								Metric: autoscaling.MetricIdentifier{
									Selector: metricLabelSelector,
								},
								Target: autoscaling.MetricTarget{
									Type:  autoscaling.ValueMetricType,
									Value: resource.NewMilliQuantity(300, resource.DecimalSI),
								},
							},
						},
					},
				},
			},
			msg: "must specify a metric name",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ExternalMetricSourceType,
							External: &autoscaling.ExternalMetricSource{
								Metric: autoscaling.MetricIdentifier{
									Name:     "foo/../",
									Selector: metricLabelSelector,
								},
								Target: autoscaling.MetricTarget{
									Type:  autoscaling.ValueMetricType,
									Value: resource.NewMilliQuantity(300, resource.DecimalSI),
								},
							},
						},
					},
				},
			},
			msg: "'/'",
		},

		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ExternalMetricSourceType,
							External: &autoscaling.ExternalMetricSource{
								Metric: autoscaling.MetricIdentifier{
									Name:     "somemetric",
									Selector: metricLabelSelector,
								},
								Target: autoscaling.MetricTarget{
									Type: autoscaling.ValueMetricType,
								},
							},
						},
					},
				},
			},
			msg: "must set either a target value for metric or a per-pod target",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ExternalMetricSourceType,
							External: &autoscaling.ExternalMetricSource{
								Metric: autoscaling.MetricIdentifier{
									Name:     "somemetric",
									Selector: metricLabelSelector,
								},
								Target: autoscaling.MetricTarget{
									Type:  autoscaling.ValueMetricType,
									Value: resource.NewMilliQuantity(-300, resource.DecimalSI),
								},
							},
						},
					},
				},
			},
			msg: "must be positive",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ExternalMetricSourceType,
							External: &autoscaling.ExternalMetricSource{
								Metric: autoscaling.MetricIdentifier{
									Name:     "somemetric",
									Selector: metricLabelSelector,
								},
								Target: autoscaling.MetricTarget{
									Type:         autoscaling.ValueMetricType,
									AverageValue: resource.NewMilliQuantity(-300, resource.DecimalSI),
								},
							},
						},
					},
				},
			},
			msg: "must be positive",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ExternalMetricSourceType,
							External: &autoscaling.ExternalMetricSource{
								Metric: autoscaling.MetricIdentifier{
									Name:     "somemetric",
									Selector: metricLabelSelector,
								},
								Target: autoscaling.MetricTarget{
									Type:         autoscaling.ValueMetricType,
									Value:        resource.NewMilliQuantity(300, resource.DecimalSI),
									AverageValue: resource.NewMilliQuantity(300, resource.DecimalSI),
								},
							},
						},
					},
				},
			},
			msg: "may not set both a target value for metric and a per-pod target",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ExternalMetricSourceType,
							External: &autoscaling.ExternalMetricSource{
								Metric: autoscaling.MetricIdentifier{
									Name:     "somemetric",
									Selector: metricLabelSelector,
								},
								Target: autoscaling.MetricTarget{
									Type:  "boogity",
									Value: resource.NewMilliQuantity(300, resource.DecimalSI),
								},
							},
						},
					},
				},
			},
			msg: "must be either Utilization, Value, or AverageValue",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ExternalMetricSourceType,
							External: &autoscaling.ExternalMetricSource{
								Metric: autoscaling.MetricIdentifier{
									Name:     "somemetric",
									Selector: metricLabelSelector,
								},
								Target: autoscaling.MetricTarget{
									Value: resource.NewMilliQuantity(300, resource.DecimalSI),
								},
							},
						},
					},
				},
			},
			msg: "must specify a metric target type",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ExternalMetricSourceType,
							External: &autoscaling.ExternalMetricSource{
								Metric: autoscaling.MetricIdentifier{
									Name:     "somemetric",
									Selector: metricLabelSelector,
								},
							},
						},
					},
				},
			},
			msg: "must specify a metric target",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{},
					},
				},
			},
			msg: "must specify a metric source type",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.MetricSourceType("InvalidType"),
						},
					},
				},
			},
			msg: "type: Unsupported value",
		},
		{
			horizontalPodAutoscaler: autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5,
					Metrics: []autoscaling.MetricSpec{
						{
							Type: autoscaling.ResourceMetricSourceType,
							Resource: &autoscaling.ResourceMetricSource{
								Name: api.ResourceCPU,
								Target: autoscaling.MetricTarget{
									Type:         autoscaling.AverageValueMetricType,
									AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
								},
							},
							Pods: &autoscaling.PodsMetricSource{
								Metric: autoscaling.MetricIdentifier{
									Name: "somemetric",
								},
								Target: autoscaling.MetricTarget{
									Type:         autoscaling.AverageValueMetricType,
									AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
								},
							},
						},
					},
				},
			},
			msg: "must populate the given metric source only",
		},
	}

	for _, c := range errorCases {
		errs := ValidateHorizontalPodAutoscaler(&c.horizontalPodAutoscaler)
		if len(errs) == 0 {
			t.Errorf("expected failure for %q", c.msg)
		} else if !strings.Contains(errs[0].Error(), c.msg) {
			t.Errorf("unexpected error: %q, expected: %q", errs[0], c.msg)
		}
	}

	sourceTypes := map[autoscaling.MetricSourceType]autoscaling.MetricSpec{
		autoscaling.ResourceMetricSourceType: {
			Resource: &autoscaling.ResourceMetricSource{
				Name: api.ResourceCPU,
				Target: autoscaling.MetricTarget{
					Type:         autoscaling.AverageValueMetricType,
					AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
				},
			},
		},
		autoscaling.PodsMetricSourceType: {
			Pods: &autoscaling.PodsMetricSource{
				Metric: autoscaling.MetricIdentifier{
					Name: "somemetric",
				},
				Target: autoscaling.MetricTarget{
					Type:         autoscaling.AverageValueMetricType,
					AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
				},
			},
		},
		autoscaling.ObjectMetricSourceType: {
			Object: &autoscaling.ObjectMetricSource{
				DescribedObject: autoscaling.CrossVersionObjectReference{
					Kind: "ReplicationController",
					Name: "myrc",
				},
				Metric: autoscaling.MetricIdentifier{
					Name: "somemetric",
				},
				Target: autoscaling.MetricTarget{
					Type:  autoscaling.ValueMetricType,
					Value: resource.NewMilliQuantity(100, resource.DecimalSI),
				},
			},
		},
	}

	for correctType, spec := range sourceTypes {
		for incorrectType := range sourceTypes {
			if correctType == incorrectType {
				continue
			}

			spec.Type = incorrectType

			errs := ValidateHorizontalPodAutoscaler(&autoscaling.HorizontalPodAutoscaler{
				ObjectMeta: metav1.ObjectMeta{Name: "myautoscaler", Namespace: metav1.NamespaceDefault},
				Spec: autoscaling.HorizontalPodAutoscalerSpec{
					ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "myrc", Kind: "ReplicationController"},
					MinReplicas:    utilpointer.Int32Ptr(1),
					MaxReplicas:    5, Metrics: []autoscaling.MetricSpec{spec},
				},
			})

			expectedMsg := "must populate information for the given metric source"

			if len(errs) == 0 {
				t.Errorf("expected failure with type of %v and spec for %v", incorrectType, correctType)
			} else if !strings.Contains(errs[0].Error(), expectedMsg) {
				t.Errorf("unexpected error: %q, expected %q", errs[0], expectedMsg)
			}
		}
	}
}

func prepareMinReplicasCases(t *testing.T, minReplicas int32) []autoscaling.HorizontalPodAutoscaler {
	metricLabelSelector, err := metav1.ParseToLabelSelector("label=value")
	if err != nil {
		t.Errorf("unable to parse label selector: %v", err)
	}
	minReplicasCases := []autoscaling.HorizontalPodAutoscaler{
		{
			ObjectMeta: metav1.ObjectMeta{
				Name:            "myautoscaler",
				Namespace:       metav1.NamespaceDefault,
				ResourceVersion: "theversion",
			},
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{
					Kind: "ReplicationController",
					Name: "myrc",
				},
				MinReplicas: utilpointer.Int32Ptr(minReplicas),
				MaxReplicas: 5,
				Metrics: []autoscaling.MetricSpec{
					{
						Type: autoscaling.ObjectMetricSourceType,
						Object: &autoscaling.ObjectMetricSource{
							DescribedObject: autoscaling.CrossVersionObjectReference{
								Kind: "ReplicationController",
								Name: "myrc",
							},
							Metric: autoscaling.MetricIdentifier{
								Name: "somemetric",
							},
							Target: autoscaling.MetricTarget{
								Type:  autoscaling.ValueMetricType,
								Value: resource.NewMilliQuantity(300, resource.DecimalSI),
							},
						},
					},
				},
			},
		},
		{
			ObjectMeta: metav1.ObjectMeta{
				Name:            "myautoscaler",
				Namespace:       metav1.NamespaceDefault,
				ResourceVersion: "theversion",
			},
			Spec: autoscaling.HorizontalPodAutoscalerSpec{
				ScaleTargetRef: autoscaling.CrossVersionObjectReference{
					Kind: "ReplicationController",
					Name: "myrc",
				},
				MinReplicas: utilpointer.Int32Ptr(minReplicas),
				MaxReplicas: 5,
				Metrics: []autoscaling.MetricSpec{
					{
						Type: autoscaling.ExternalMetricSourceType,
						External: &autoscaling.ExternalMetricSource{
							Metric: autoscaling.MetricIdentifier{
								Name:     "somemetric",
								Selector: metricLabelSelector,
							},
							Target: autoscaling.MetricTarget{
								Type:         autoscaling.AverageValueMetricType,
								AverageValue: resource.NewMilliQuantity(300, resource.DecimalSI),
							},
						},
					},
				},
			},
		},
	}
	return minReplicasCases
}

func TestValidateHorizontalPodAutoscalerScaleToZeroEnabled(t *testing.T) {
	// Enable HPAScaleToZero feature gate.
	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HPAScaleToZero, true)()

	zeroMinReplicasCases := prepareMinReplicasCases(t, 0)
	for _, successCase := range zeroMinReplicasCases {
		if errs := ValidateHorizontalPodAutoscaler(&successCase); len(errs) != 0 {
			t.Errorf("expected success: %v", errs)
		}
	}
}

func TestValidateHorizontalPodAutoscalerScaleToZeroDisabled(t *testing.T) {
	// Disable HPAScaleToZero feature gate.
	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HPAScaleToZero, false)()

	zeroMinReplicasCases := prepareMinReplicasCases(t, 0)
	errorMsg := "must be greater than or equal to 1"

	for _, errorCase := range zeroMinReplicasCases {
		errs := ValidateHorizontalPodAutoscaler(&errorCase)
		if len(errs) == 0 {
			t.Errorf("expected failure for %q", errorMsg)
		} else if !strings.Contains(errs[0].Error(), errorMsg) {
			t.Errorf("unexpected error: %q, expected: %q", errs[0], errorMsg)
		}
	}

	nonZeroMinReplicasCases := prepareMinReplicasCases(t, 1)

	for _, successCase := range nonZeroMinReplicasCases {
		successCase.Spec.MinReplicas = utilpointer.Int32Ptr(1)
		if errs := ValidateHorizontalPodAutoscaler(&successCase); len(errs) != 0 {
			t.Errorf("expected success: %v", errs)
		}
	}
}

func TestValidateHorizontalPodAutoscalerUpdateScaleToZeroEnabled(t *testing.T) {
	// Enable HPAScaleToZero feature gate.
	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HPAScaleToZero, true)()

	zeroMinReplicasCases := prepareMinReplicasCases(t, 0)
	nonZeroMinReplicasCases := prepareMinReplicasCases(t, 1)

	for i, zeroCase := range zeroMinReplicasCases {
		nonZeroCase := nonZeroMinReplicasCases[i]

		if errs := ValidateHorizontalPodAutoscalerUpdate(&nonZeroCase, &zeroCase); len(errs) != 0 {
			t.Errorf("expected success: %v", errs)
		}

		if errs := ValidateHorizontalPodAutoscalerUpdate(&zeroCase, &nonZeroCase); len(errs) != 0 {
			t.Errorf("expected success: %v", errs)
		}
	}
}

func TestValidateHorizontalPodAutoscalerScaleToZeroUpdateDisabled(t *testing.T) {
	// Disable HPAScaleToZero feature gate.
	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HPAScaleToZero, false)()

	zeroMinReplicasCases := prepareMinReplicasCases(t, 0)
	nonZeroMinReplicasCases := prepareMinReplicasCases(t, 1)
	errorMsg := "must be greater than or equal to 1"

	for i, zeroCase := range zeroMinReplicasCases {
		nonZeroCase := nonZeroMinReplicasCases[i]
		errs := ValidateHorizontalPodAutoscalerUpdate(&zeroCase, &nonZeroCase)

		if len(errs) == 0 {
			t.Errorf("expected failure for %q", errorMsg)
		} else if !strings.Contains(errs[0].Error(), errorMsg) {
			t.Errorf("unexpected error: %q, expected: %q", errs[0], errorMsg)
		}

		if errs := ValidateHorizontalPodAutoscalerUpdate(&zeroCase, &zeroCase); len(errs) != 0 {
			t.Errorf("expected success: %v", errs)
		}

		if errs := ValidateHorizontalPodAutoscalerUpdate(&nonZeroCase, &zeroCase); len(errs) != 0 {
			t.Errorf("expected success: %v", errs)
		}
	}
}


text:
const axios = require('axios');
const urllib = require('url-lib');
const cache = require('memory-cache');

import blogRepository from '../../../api/repository/blog'

import {createViewPath} from '../create-view-path'

const CACHED_TIME_MS = 60 * 60 * 24
const YOUTUBE_CHANNEL_ID = process.env.YOUTUBE_CHANNEL_ID;
const YOUTUBE_API_KEY = process.env.YOUTUBE_API_KEY;
const YOUTUBE_API_ENDPOINT = urllib.formatUrl(
  'https://www.googleapis.com/youtube/v3/search',
  {
    part: 'snippet', // overwrites existing `sort` param in URL
    channelId: YOUTUBE_CHANNEL_ID,
    maxResults: 1,
    order: 'date',
    type: 'video',
    key: YOUTUBE_API_KEY
  },
)

const getLatestVideo = () => {
	return new Promise((resolve, reject) => {
		try {
			const cachedLatestVideo = cache.get('youtube-latest-video');

			if (!cachedLatestVideo) {
				return axios.get(YOUTUBE_API_ENDPOINT).then((youtubeResponse) => {
					const latestVideo = youtubeResponse.data.items[0]

					cache.put('youtube-latest-video', latestVideo, CACHED_TIME_MS)

					return resolve(latestVideo)
				})
			}

			return resolve(cachedLatestVideo)
		} catch (error) {
			return resolve([])
		}
	})
}

export const getLinksPage = async (_, res) => {
	try {
		const posts = await blogRepository.getMostRecentPosts()
		const latestPost = posts[0]

		const latestVideo = await getLatestVideo()
		const pinnedLink = {
			url: 'https://developersindepth.com/',
			title: 'Get your invite to Developers In Depth!'
		}
		const projects = [
			{
				url: 'https://ferreiro.me/?utm_source=links&utm_medium=cta&utm_campaign=links-ferreiro',
				title: 'Ferreiro.me',
				image: '/links_jorge_ferreiro_project.jpg',
			},
			{
				url: 'https://www.developersindepth.com/?utm_source=links&utm_medium=cta&utm_campaign=links-ferreiro',
				title: 'Developers In Depth',
				image: '/links_developers_in_depth_by_jorge_ferreiro_project.jpg',
			}
		]

		return res.render(createViewPath('links', 'links.pug'), {
	        title: 'Links Jorge Ferreiro',
	        path: 'links',
	        pinnedLink,
	        latestPost,
			latestVideo,
			projects
	    })
	} catch (error) {
		console.log(error)
		return res.json({ error })
	}
}


text:
<?php
/**
 * A validator performs syntax and possibly semantic validation of a single
 * piece of data from an untrusted source.
 *
 * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) <a
 *         href="http://www.aspectsecurity.com">Aspect Security</a>
 * @since June 1, 2007
 * @see org.owasp.esapi.Validator
 */
class DateValidationRule extends BaseValidationRule {

	private $format;

	public function DateValidationRule( $typeName, $encoder, $newFormat ) {
		parent::BaseValidationRule( $typeName, $encoder );
		if ( $newFormat=='' ) {
			$newFormat='%Y-%m-%d';
		}
		$this->setDateFormat( $newFormat );
	}

    public function setDateFormat( $newFormat ) {
        if ($newFormat == null) throw new RuntimeException("DateValidationRule.setDateFormat requires a non-null DateFormat");
        $this->format = $newFormat;
    }

	public function getValid( $context, $input,$errorlist=null )  {

		// check null
	    if ( strlen($input)==0 ) {
			if ($this->allowNull) return null;
			throw new ValidationException( $context.": Input date required", "Input date required: context=".$context.", input=".$input, $context );
	    }

	    // canonicalize
	    $canonical = null;
	    try {
	    	$canonical = $this->encoder->canonicalize( $input );
	    } catch (EncodingException $e) {
	        throw new ValidationException( $context.": Invalid date input. Encoding problem detected.", "Error canonicalizing user input", $e, $context);
	    }

		try {
			$date=date_create($canonical);
			// validation passed
			return $date;
		} catch (Exception $e) {
			throw new ValidationException( $context.": Invalid date must follow the ".$format->getNumberFormat() + " format", "Invalid date: context=".$context.", format=".$format.", input=".$input, $e, $context);
		}
	}

	public function sanitize( $context, $input )  {
		return date();
	}

}

?>


text:
- [`latest`, `5`, `5.20`, `5.20.1` (*5.020.001-64bit/Dockerfile*)](https://github.com/perl/docker-perl/blob/r20141106.0/5.020.001-64bit/Dockerfile)
- [`5.18`, `5.18.4` (*5.018.004-64bit/Dockerfile*)](https://github.com/perl/docker-perl/blob/r20141106.0/5.018.004-64bit/Dockerfile)
- [`latest-threaded`, `5-threaded`, `5.20-threaded`, `5.20.1-threaded` (*5.020.001-64bit,threaded/Dockerfile*)](https://github.com/perl/docker-perl/blob/r20141106.0/5.020.001-64bit,threaded/Dockerfile)
- [`5.18-threaded`, `5.18.4-threaded` (*5.018.004-64bit,threaded/Dockerfile*)](https://github.com/perl/docker-perl/blob/r20141106.0/5.018.004-64bit,threaded/Dockerfile)

For more information about this image and its history, please see the [relevant
manifest file
(`library/perl`)](https://github.com/docker-library/official-images/blob/master/library/perl)
in the [`docker-library/official-images` GitHub
repo](https://github.com/docker-library/official-images).

# What is Perl?

Perl is a high-level, general-purpose, interpreted, dynamic programming
language. The Perl language borrows features from other programming languages,
including C, shell scripting (sh), AWK, and sed.

> [wikipedia.org/wiki/Perl](https://en.wikipedia.org/wiki/Perl)

![logo](https://raw.githubusercontent.com/docker-library/docs/master/perl/logo.png)

# How to use this image

## Create a `Dockerfile` in your Perl app project

    FROM perl:5.20
    COPY . /usr/src/myapp
    WORKDIR /usr/src/myapp
    CMD [ "perl", "./your-daemon-or-script.pl" ]

Then, build and run the Docker image:

    docker build -t my-perl-app .
    docker run -it --rm --name my-running-app my-perl-app

## Run a single Perl script

For many simple, single file projects, you may find it inconvenient to write a
complete `Dockerfile`. In such cases, you can run a Perl script by using the
Perl Docker image directly:

    docker run -it --rm --name my-running-script -v "$(pwd)":/usr/src/myapp -w /usr/src/myapp perl:5.20 perl your-daemon-or-script.pl

# License

View [license information](http://dev.perl.org/licenses/)
for the software contained in this image.

# User Feedback

## Issues

If you have any problems with or questions about this image, please contact us
 through a [GitHub issue](https://github.com/Perl/docker-perl/issues).

You can also reach many of the official image maintainers via the
`#docker-library` IRC channel on [Freenode](https://freenode.net).

## Contributing

You are invited to contribute new features, fixes, or updates, large or small;
we are always thrilled to receive pull requests, and do our best to process them
as fast as we can.

Before you start to code, we recommend discussing your plans
through a [GitHub issue](https://github.com/Perl/docker-perl/issues), especially for more ambitious
contributions. This gives other contributors a chance to point you in the right
direction, give you feedback on your design, and help you find out if someone
else is working on the same thing.


text:
package com.github.neuralnetworks.calculation;

import com.github.neuralnetworks.architecture.Layer;
import com.github.neuralnetworks.architecture.NeuralNetwork;
import com.github.neuralnetworks.calculation.memory.ValuesProvider;

import java.io.Serializable;
import java.util.Set;

/**
 * The implementations of this interface provide a way of propagating results
 * from one layer to the next
 */
public interface LayerCalculator extends Serializable {

    /**
     * This method receives a target layer to calculate, a list of calculated layer results and a list of layers that have already been calculated.
     * This information is enough for the target layer can be calculated
     *
     * @param calculatedLayers
     *            - existing results
     * @param layer
     *            - the layer to be calculated
     */
    /**
     * @param calculatedLayers
     *            - calculated layers that are provided as input
     * @param results
     *            - where the results are stored
     * @param layer
     *            - current layer
     * @param neuralNetwork
     *            - the network of context for calculation
     */
    public void calculate(NeuralNetwork neuralNetwork, Layer layer, Set<Layer> calculatedLayers, ValuesProvider results);
}


text:
/* @flow */

import api from 'core/api';

export const RECEIVE: 'project/RECEIVE' = 'project/RECEIVE';
export const REQUEST: 'project/REQUEST' = 'project/REQUEST';

export type Tag = {|
    +slug: string,
    +name: string,
    +priority: number,
|};

type Project = {
    slug: string,
    name: string,
    info: string,
    tags: Array<Tag>,
};

/**
 * Notify that project data is being fetched.
 */
export type RequestAction = {
    +type: typeof REQUEST,
};
export function request(): RequestAction {
    return {
        type: REQUEST,
    };
}

/**
 * Receive project data.
 */
export type ReceiveAction = {
    +type: typeof RECEIVE,
    +slug: string,
    +name: string,
    +info: string,
    +tags: Array<Tag>,
};
export function receive(project: Project): ReceiveAction {
    return {
        type: RECEIVE,
        slug: project.slug,
        name: project.name,
        info: project.info,
        tags: project.tags,
    };
}

/**
 * Get data about the current project.
 */
export function get(slug: string): Function {
    return async (dispatch) => {
        // When 'all-projects' are selected, we do not fetch data.
        if (slug === 'all-projects') {
            return;
        }
        dispatch(request());
        const results = await api.project.get(slug);
        dispatch(receive(results.data.project));
    };
}

export default {
    get,
    receive,
    request,
};